home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / system-config-printer / system-config-printer.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-10-12  |  177.5 KB  |  6,401 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import config
  5. import errno
  6. import sys
  7. import os
  8. import tempfile
  9. import time
  10. import traceback
  11. import re
  12. import httplib
  13. import glob
  14. import subprocess
  15. import signal
  16. import thread
  17. import dbus
  18.  
  19. try:
  20.     import gtk.glade as gtk
  21. except RuntimeError:
  22.     e = None
  23.     print 'system-config-printer:', e
  24.     print 'This is a graphical application and requires DISPLAY to be set.'
  25.     sys.exit(1)
  26.  
  27. import gnome
  28. gtk.about_dialog_set_url_hook((lambda x, y: gnome.url_show(y)))
  29. gtk.about_dialog_set_email_hook((lambda x, y: gnome.url_show('mailto:' + y)))
  30.  
  31. def show_help():
  32.     print '\nThis is system-config-printer, a CUPS server configuration program.\n\nOptions:\n\n  --setup-printer URI\n            Select the (detected) CUPS device URI on start-up,\n            and run the new-printer wizard for it.\n\n  --configure-printer NAME\n            Select the named printer on start-up, and open its\n            properties dialog.\n\n  --choose-driver NAME\n            Select the named printer on start-up, and display\n            the list of drivers.\n\n  --print-test-page NAME\n            Select the named printer on start-up and print a\n            test page to it.\n\n  --no-focus-on-map\n            Do not focus the main window, to prevent focus \n            stealing\n\n  --debug   Enable debugging output.\n'
  33.  
  34. if len(sys.argv) > 1 and sys.argv[1] == '--help':
  35.     show_help()
  36.     sys.exit(0)
  37.  
  38. import cups
  39. cups.require('1.9.42')
  40.  
  41. try:
  42.     import pysmb
  43.     PYSMB_AVAILABLE = True
  44. except:
  45.     PYSMB_AVAILABLE = False
  46.  
  47. import cupshelpers
  48. import options
  49. import gobject
  50. from glade import GtkGUI
  51. from optionwidgets import OptionWidget
  52. from debug import *
  53. import probe_printer
  54. import gtk_label_autowrap
  55. from gtk_treeviewtooltips import TreeViewTooltips
  56. import urllib
  57. import troubleshoot
  58. import jobviewer
  59. import authconn
  60. import monitor
  61. from smburi import SMBURI
  62. import errordialogs
  63. from errordialogs import *
  64. import installpackage
  65. import userdefault
  66. from AdvancedServerSettings import AdvancedServerSettingsDialog
  67. from PhysicalDevice import PhysicalDevice
  68. from ToolbarSearchEntry import *
  69. from GroupsPane import *
  70. from GroupsPaneModel import *
  71. from SearchCriterion import *
  72. import gtkinklevel
  73. import pango
  74. import statereason
  75. domain = 'system-config-printer'
  76. import locale
  77.  
  78. try:
  79.     locale.setlocale(locale.LC_ALL, '')
  80. except locale.Error:
  81.     os.environ['LC_ALL'] = 'C'
  82.     locale.setlocale(locale.LC_ALL, '')
  83.  
  84. from gettext import gettext as _
  85. monitor.set_gettext_function(_)
  86. errordialogs.set_gettext_function(_)
  87. authconn.set_gettext_function(_)
  88. import gettext
  89. gettext.textdomain(domain)
  90. gettext.bindtextdomain(domain, config.localedir)
  91. gtk.glade.textdomain(domain)
  92. gtk.glade.bindtextdomain(domain, config.localedir)
  93. import ppdippstr
  94. pkgdata = config.pkgdatadir
  95. iconpath = os.path.join(pkgdata, 'icons/')
  96. sys.path.append(pkgdata)
  97. busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
  98. ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
  99. TEXT_start_firewall_tool = _('To do this, select System->Administration->Firewall from the main menu.')
  100.  
  101. try:
  102.     try_CUPS_SERVER_REMOTE_ANY = cups.CUPS_SERVER_REMOTE_ANY
  103. except AttributeError:
  104.     try_CUPS_SERVER_REMOTE_ANY = '_remote_any'
  105.  
  106.  
  107. def validDeviceURI(uri):
  108.     '''Returns True is the provided URI is valid.'''
  109.     (scheme, rest) = urllib.splittype(uri)
  110.     if scheme == None or scheme == '':
  111.         return False
  112.     if rest == None or rest.strip('/') == '':
  113.         return False
  114.     return True
  115.  
  116.  
  117. def CUPS_server_hostname():
  118.     host = cups.getServer()
  119.     if host[0] == '/':
  120.         return 'localhost'
  121.     return host
  122.  
  123.  
  124. def moveClassMembers(treeview_from, treeview_to):
  125.     selection = treeview_from.get_selection()
  126.     (model_from, rows) = selection.get_selected_rows()
  127.     rows = [ gtk.TreeRowReference(model_from, row) for row in rows ]
  128.     model_to = treeview_to.get_model()
  129.     for row in rows:
  130.         path = row.get_path()
  131.         iter = model_from.get_iter(path)
  132.         row_data = model_from.get(iter, 0)
  133.         model_to.append(row_data)
  134.         model_from.remove(iter)
  135.     
  136.  
  137.  
  138. def getCurrentClassMembers(treeview):
  139.     model = treeview.get_model()
  140.     iter = model.get_iter_root()
  141.     result = []
  142.     while iter:
  143.         result.append(model.get(iter, 0)[0])
  144.         iter = model.iter_next(iter)
  145.     result.sort()
  146.     return result
  147.  
  148.  
  149. def on_delete_just_hide(widget, event):
  150.     widget.hide()
  151.     return True
  152.  
  153.  
  154. class GUI(GtkGUI, monitor.Watcher):
  155.     printer_states = {
  156.         cups.IPP_PRINTER_IDLE: _('Idle'),
  157.         cups.IPP_PRINTER_PROCESSING: _('Processing'),
  158.         cups.IPP_PRINTER_BUSY: _('Busy'),
  159.         cups.IPP_PRINTER_STOPPED: _('Stopped') }
  160.     
  161.     def __init__(self, setup_printer = None, configure_printer = None, change_ppd = False, devid = '', print_test_page = False, focus_on_map = True):
  162.         
  163.         try:
  164.             self.language = locale.getlocale(locale.LC_MESSAGES)
  165.             self.encoding = locale.getlocale(locale.LC_CTYPE)
  166.         except:
  167.             nonfatalException()
  168.             os.environ['LC_ALL'] = 'C'
  169.             locale.setlocale(locale.LC_ALL, '')
  170.             self.language = locale.getlocale(locale.LC_MESSAGES)
  171.             self.encoding = locale.getlocale(locale.LC_CTYPE)
  172.  
  173.         self.printer = None
  174.         self.conflicts = set()
  175.         if not self.printer or self.printer.getServer():
  176.             pass
  177.         self.connect_server = cups.getServer()
  178.         self.connect_encrypt = cups.getEncryption()
  179.         self.connect_user = cups.getUser()
  180.         self.changed = set()
  181.         self.servers = set((self.connect_server,))
  182.         self.server_is_publishing = False
  183.         self.devid = devid
  184.         self.focus_on_map = focus_on_map
  185.         self.updating_widgets = False
  186.         self.getWidgets({
  187.             'PrintersWindow': [
  188.                 'PrintersWindow',
  189.                 'view_area_vbox',
  190.                 'view_area_scrolledwindow',
  191.                 'dests_iconview',
  192.                 'statusbarMain',
  193.                 'toolbar',
  194.                 'server_settings_menu_entry',
  195.                 'new_printer',
  196.                 'new_class',
  197.                 'group_menubar_item',
  198.                 'printer_menubar_item',
  199.                 'view_discovered_printers',
  200.                 'view_groups'],
  201.             'AboutDialog': [
  202.                 'AboutDialog'],
  203.             'WaitWindow': [
  204.                 'WaitWindow',
  205.                 'lblWait'],
  206.             'ConnectDialog': [
  207.                 'ConnectDialog',
  208.                 'chkEncrypted',
  209.                 'cmbServername',
  210.                 'btnConnect'],
  211.             'ConnectingDialog': [
  212.                 'ConnectingDialog',
  213.                 'lblConnecting',
  214.                 'pbarConnecting'],
  215.             'NewPrinterName': [
  216.                 'NewPrinterName',
  217.                 'entCopyName',
  218.                 'btnCopyOk'],
  219.             'ServerSettingsDialog': [
  220.                 'ServerSettingsDialog',
  221.                 'chkServerBrowse',
  222.                 'chkServerShare',
  223.                 'chkServerShareAny',
  224.                 'chkServerRemoteAdmin',
  225.                 'chkServerAllowCancelAll',
  226.                 'chkServerLogDebug',
  227.                 'hboxServerBrowse'],
  228.             'PrinterPropertiesDialog': [
  229.                 'PrinterPropertiesDialog',
  230.                 'tvPrinterProperties',
  231.                 'btnPrinterPropertiesCancel',
  232.                 'btnPrinterPropertiesOK',
  233.                 'btnPrinterPropertiesApply',
  234.                 'btnPrinterPropertiesClose',
  235.                 'ntbkPrinter',
  236.                 'entPDescription',
  237.                 'entPLocation',
  238.                 'lblPMakeModel',
  239.                 'lblPMakeModel2',
  240.                 'lblPState',
  241.                 'entPDevice',
  242.                 'lblPDevice2',
  243.                 'btnSelectDevice',
  244.                 'btnChangePPD',
  245.                 'chkPEnabled',
  246.                 'chkPAccepting',
  247.                 'chkPShared',
  248.                 'lblNotPublished',
  249.                 'btnPrintTestPage',
  250.                 'btnSelfTest',
  251.                 'btnCleanHeads',
  252.                 'btnConflict',
  253.                 'cmbPStartBanner',
  254.                 'cmbPEndBanner',
  255.                 'cmbPErrorPolicy',
  256.                 'cmbPOperationPolicy',
  257.                 'rbtnPAllow',
  258.                 'rbtnPDeny',
  259.                 'tvPUsers',
  260.                 'entPUser',
  261.                 'btnPAddUser',
  262.                 'btnPDelUser',
  263.                 'lblPInstallOptions',
  264.                 'swPInstallOptions',
  265.                 'vbPInstallOptions',
  266.                 'swPOptions',
  267.                 'lblPOptions',
  268.                 'vbPOptions',
  269.                 'algnClassMembers',
  270.                 'vbClassMembers',
  271.                 'lblClassMembers',
  272.                 'tvClassMembers',
  273.                 'tvClassNotMembers',
  274.                 'btnClassAddMember',
  275.                 'btnClassDelMember',
  276.                 'btnRefreshMarkerLevels',
  277.                 'tvPrinterStateReasons',
  278.                 'ntbkPrinterStateReasons',
  279.                 'sbJOCopies',
  280.                 'btnJOResetCopies',
  281.                 'cmbJOOrientationRequested',
  282.                 'btnJOResetOrientationRequested',
  283.                 'cbJOFitplot',
  284.                 'btnJOResetFitplot',
  285.                 'cmbJONumberUp',
  286.                 'btnJOResetNumberUp',
  287.                 'cmbJONumberUpLayout',
  288.                 'btnJOResetNumberUpLayout',
  289.                 'sbJOBrightness',
  290.                 'btnJOResetBrightness',
  291.                 'cmbJOFinishings',
  292.                 'btnJOResetFinishings',
  293.                 'sbJOJobPriority',
  294.                 'btnJOResetJobPriority',
  295.                 'cmbJOMedia',
  296.                 'btnJOResetMedia',
  297.                 'cmbJOSides',
  298.                 'btnJOResetSides',
  299.                 'cmbJOHoldUntil',
  300.                 'btnJOResetHoldUntil',
  301.                 'cbJOMirror',
  302.                 'btnJOResetMirror',
  303.                 'sbJOScaling',
  304.                 'btnJOResetScaling',
  305.                 'sbJOSaturation',
  306.                 'btnJOResetSaturation',
  307.                 'sbJOHue',
  308.                 'btnJOResetHue',
  309.                 'sbJOGamma',
  310.                 'btnJOResetGamma',
  311.                 'sbJOCpi',
  312.                 'btnJOResetCpi',
  313.                 'sbJOLpi',
  314.                 'btnJOResetLpi',
  315.                 'sbJOPageLeft',
  316.                 'btnJOResetPageLeft',
  317.                 'sbJOPageRight',
  318.                 'btnJOResetPageRight',
  319.                 'sbJOPageTop',
  320.                 'btnJOResetPageTop',
  321.                 'sbJOPageBottom',
  322.                 'btnJOResetPageBottom',
  323.                 'cbJOPrettyPrint',
  324.                 'btnJOResetPrettyPrint',
  325.                 'cbJOWrap',
  326.                 'btnJOResetWrap',
  327.                 'sbJOColumns',
  328.                 'btnJOResetColumns',
  329.                 'tblJOOther',
  330.                 'entNewJobOption',
  331.                 'btnNewJobOption',
  332.                 'vboxMarkerLevels',
  333.                 'btnRefreshMarkerLevels'] })
  334.         self.PrintersWindow.set_focus_on_map(self.focus_on_map)
  335.         self.PrintersWindow.show()
  336.         for dialog in [
  337.             self.PrinterPropertiesDialog,
  338.             self.ServerSettingsDialog]:
  339.             dialog.connect('delete-event', on_delete_just_hide)
  340.         
  341.         self.ConnectingDialog.connect('delete-event', self.on_connectingdialog_delete)
  342.         self.tooltips = gtk.Tooltips()
  343.         self.tooltips.enable()
  344.         gtk.window_set_default_icon_name('printer')
  345.         self.btnNew = gtk.MenuToolButton('gtk-new')
  346.         self.btnNew.set_is_important(True)
  347.         newmenu = gtk.Menu()
  348.         newprinter = gtk.ImageMenuItem(_('Printer'))
  349.         printericon = gtk.Image()
  350.         printericon.set_from_icon_name('printer', gtk.ICON_SIZE_MENU)
  351.         newprinter.set_image(printericon)
  352.         newprinter.connect('activate', self.on_new_printer_activate)
  353.         self.btnNew.connect('clicked', self.on_new_printer_activate)
  354.         newclass = gtk.ImageMenuItem(_('Class'))
  355.         classicon = gtk.Image()
  356.         classicon.set_from_icon_name('gtk-dnd-multiple', gtk.ICON_SIZE_MENU)
  357.         newclass.set_image(classicon)
  358.         newclass.connect('activate', self.on_new_class_activate)
  359.         newprinter.show()
  360.         newclass.show()
  361.         newmenu.attach(newprinter, 0, 1, 0, 1)
  362.         newmenu.attach(newclass, 0, 1, 1, 2)
  363.         self.btnNew.set_menu(newmenu)
  364.         self.toolbar.add(self.btnNew)
  365.         self.toolbar.add(gtk.SeparatorToolItem())
  366.         refreshbutton = gtk.ToolButton('gtk-refresh')
  367.         refreshbutton.connect('clicked', self.on_btnRefresh_clicked)
  368.         self.toolbar.add(refreshbutton)
  369.         self.toolbar.show_all()
  370.         printer_manager_action_group = gtk.ActionGroup('PrinterManagerActionGroup')
  371.         printer_manager_action_group.add_actions([
  372.             ('rename-printer', None, _('_Rename'), None, None, self.on_rename_activate),
  373.             ('copy-printer', gtk.STOCK_COPY, None, '<Ctrl>c', None, self.on_copy_activate),
  374.             ('delete-printer', gtk.STOCK_DELETE, None, None, None, self.on_delete_activate),
  375.             ('set-default-printer', gtk.STOCK_HOME, _('Set As De_fault'), None, None, self.on_set_as_default_activate),
  376.             ('edit-printer', gtk.STOCK_PROPERTIES, None, None, None, self.on_edit_activate),
  377.             ('create-class', gtk.STOCK_DND_MULTIPLE, _('_Create class'), None, None, self.on_create_class_activate),
  378.             ('view-print-queue', gtk.STOCK_FIND, _('View Print _Queue'), None, None, self.on_view_print_queue_activate),
  379.             ('add-to-group', None, _('_Add to Group'), None, None, None),
  380.             ('save-as-group', None, _('Save Results as _Group'), None, None, self.on_save_as_group_activate),
  381.             ('save-as-search-group', None, _('Save Filter as _Search Group'), None, None, self.on_save_as_search_group_activate)])
  382.         printer_manager_action_group.add_toggle_actions([
  383.             ('enable-printer', None, _('E_nabled'), None, None, self.on_enabled_activate),
  384.             ('share-printer', None, _('_Shared'), None, None, self.on_shared_activate)])
  385.         printer_manager_action_group.add_radio_actions([
  386.             ('filter-name', None, _('Name')),
  387.             ('filter-description', None, _('Description')),
  388.             ('filter-location', None, _('Location')),
  389.             ('filter-manufacturer', None, _('Manufacturer / Model'))], 1, self.on_filter_criterion_changed)
  390.         for action in printer_manager_action_group.list_actions():
  391.             action.set_sensitive(False)
  392.         
  393.         printer_manager_action_group.get_action('view-print-queue').set_sensitive(True)
  394.         printer_manager_action_group.get_action('filter-name').set_sensitive(True)
  395.         printer_manager_action_group.get_action('filter-description').set_sensitive(True)
  396.         printer_manager_action_group.get_action('filter-location').set_sensitive(True)
  397.         printer_manager_action_group.get_action('filter-manufacturer').set_sensitive(True)
  398.         self.ui_manager = gtk.UIManager()
  399.         self.ui_manager.insert_action_group(printer_manager_action_group, -1)
  400.         self.ui_manager.add_ui_from_string('\n<ui>\n <accelerator action="rename-printer"/>\n <accelerator action="copy-printer"/>\n <accelerator action="delete-printer"/>\n <accelerator action="set-default-printer"/>\n <accelerator action="edit-printer"/>\n <accelerator action="create-class"/>\n <accelerator action="view-print-queue"/>\n <accelerator action="add-to-group"/>\n <accelerator action="save-as-group"/>\n <accelerator action="save-as-search-group"/>\n <accelerator action="enable-printer"/>\n <accelerator action="share-printer"/>\n <accelerator action="filter-name"/>\n <accelerator action="filter-description"/>\n <accelerator action="filter-location"/>\n <accelerator action="filter-manufacturer"/>\n</ui>\n')
  401.         self.ui_manager.ensure_update()
  402.         self.PrintersWindow.add_accel_group(self.ui_manager.get_accel_group())
  403.         self.printer_context_menu = gtk.Menu()
  404.         for action_name in [
  405.             'edit-printer',
  406.             'copy-printer',
  407.             'rename-printer',
  408.             'delete-printer',
  409.             None,
  410.             'enable-printer',
  411.             'share-printer',
  412.             'create-class',
  413.             'set-default-printer',
  414.             None,
  415.             'add-to-group',
  416.             'view-print-queue']:
  417.             if not action_name:
  418.                 item = gtk.SeparatorMenuItem()
  419.             else:
  420.                 action = printer_manager_action_group.get_action(action_name)
  421.                 item = action.create_menu_item()
  422.             item.show()
  423.             self.printer_context_menu.append(item)
  424.         
  425.         self.printer_menubar_item.set_submenu(self.printer_context_menu)
  426.         self.jobviewers = []
  427.         for combobox in [
  428.             self.cmbPStartBanner,
  429.             self.cmbPEndBanner,
  430.             self.cmbPErrorPolicy,
  431.             self.cmbPOperationPolicy]:
  432.             cell = gtk.CellRendererText()
  433.             combobox.clear()
  434.             combobox.pack_start(cell, True)
  435.             combobox.add_attribute(cell, 'text', 0)
  436.         
  437.         btn = self.btnRefreshMarkerLevels
  438.         btn.connect('clicked', self.on_btnRefreshMarkerLevels_clicked)
  439.         column = gtk.TreeViewColumn(_('Message'))
  440.         icon = gtk.CellRendererPixbuf()
  441.         column.pack_start(icon, False)
  442.         text = gtk.CellRendererText()
  443.         column.pack_start(text, False)
  444.         column.set_cell_data_func(icon, self.set_printer_state_reason_icon)
  445.         column.set_cell_data_func(text, self.set_printer_state_reason_text)
  446.         column.set_resizable(True)
  447.         self.tvPrinterStateReasons.append_column(column)
  448.         selection = self.tvPrinterStateReasons.get_selection()
  449.         selection.set_mode(gtk.SELECTION_NONE)
  450.         store = gtk.ListStore(int, str)
  451.         self.tvPrinterStateReasons.set_model(store)
  452.         self.newPrinterGUI = np = NewPrinterGUI(self)
  453.         np.NewPrinterWindow.set_transient_for(self.PrintersWindow)
  454.         self.AboutDialog.set_program_name(domain)
  455.         self.AboutDialog.set_version(config.VERSION)
  456.         self.AboutDialog.set_icon_name('printer')
  457.         
  458.         class UnobtrusiveButton(gtk.Button):
  459.             
  460.             def __init__(self, **args):
  461.                 gtk.Button.__init__(self, **args)
  462.                 self.set_relief(gtk.RELIEF_NONE)
  463.                 label = self.get_child()
  464.                 text = label.get_text()
  465.                 label.set_use_markup(True)
  466.                 label.set_markup('<span size="small" ' + 'underline="single" ' + 'color="#0000ee">%s</span>' % text)
  467.  
  468.  
  469.         problems = UnobtrusiveButton(label = _('Problems?'))
  470.         self.hboxServerBrowse.pack_end(problems, False, False, 0)
  471.         problems.connect('clicked', self.on_problems_button_clicked)
  472.         problems.show()
  473.         self.static_tabs = 3
  474.         gtk_label_autowrap.set_autowrap(self.PrintersWindow)
  475.         
  476.         try:
  477.             self.cups = authconn.Connection(self.PrintersWindow)
  478.         except RuntimeError:
  479.             self.cups = None
  480.  
  481.         self.status_context_id = self.statusbarMain.get_context_id('Connection')
  482.         self.setConnected()
  483.         self.setup_toolbar_for_search_entry()
  484.         self.current_filter_text = ''
  485.         self.current_filter_mode = 'filter-name'
  486.         self.groups_pane = GroupsPane()
  487.         self.current_groups_pane_item = self.groups_pane.get_selected_item()
  488.         self.groups_pane.connect('item-activated', self.on_groups_pane_item_activated)
  489.         self.groups_pane.connect('items-changed', self.on_groups_pane_items_changed)
  490.         self.PrintersWindow.add_accel_group(self.groups_pane.ui_manager.get_accel_group())
  491.         self.view_area_hpaned = gtk.HPaned()
  492.         self.view_area_hpaned.add1(self.groups_pane)
  493.         self.groups_pane_visible = False
  494.         if self.groups_pane.n_groups() > 0:
  495.             self.view_groups.set_active(True)
  496.         
  497.         self.group_menubar_item.set_submenu(self.groups_pane.groups_menu)
  498.         self.add_to_group_menu = gtk.Menu()
  499.         self.update_add_to_group_menu()
  500.         action = printer_manager_action_group.get_action('add-to-group')
  501.         for proxy in action.get_proxies():
  502.             if isinstance(proxy, gtk.MenuItem):
  503.                 item = proxy
  504.                 break
  505.                 continue
  506.         
  507.         item.set_submenu(self.add_to_group_menu)
  508.         menu = gtk.Menu()
  509.         for action_name in [
  510.             'filter-name',
  511.             'filter-description',
  512.             'filter-location',
  513.             'filter-manufacturer',
  514.             None,
  515.             'save-as-group',
  516.             'save-as-search-group']:
  517.             if not action_name:
  518.                 item = gtk.SeparatorMenuItem()
  519.             else:
  520.                 action = printer_manager_action_group.get_action(action_name)
  521.                 item = action.create_menu_item()
  522.             menu.append(item)
  523.         
  524.         menu.show_all()
  525.         self.search_entry.set_drop_down_menu(menu)
  526.         self.mainlist = gtk.ListStore(gobject.TYPE_PYOBJECT, gtk.gdk.Pixbuf, gobject.TYPE_STRING, gobject.TYPE_STRING)
  527.         self.dests_iconview.set_model(self.mainlist)
  528.         self.dests_iconview.set_column_spacing(30)
  529.         self.dests_iconview.set_row_spacing(20)
  530.         self.dests_iconview.set_pixbuf_column(1)
  531.         self.dests_iconview.set_text_column(2)
  532.         self.dests_iconview.set_tooltip_column(3)
  533.         self.dests_iconview.connect('key-press-event', self.dests_iconview_key_press_event)
  534.         self.dests_iconview.connect('item-activated', self.dests_iconview_item_activated)
  535.         self.dests_iconview.connect('selection-changed', self.dests_iconview_selection_changed)
  536.         self.dests_iconview.connect('button-press-event', self.dests_iconview_button_press_event)
  537.         self.dests_iconview.connect('popup-menu', self.dests_iconview_popup_menu)
  538.         self.dests_iconview_selection_changed(self.dests_iconview)
  539.         self.dests_iconview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [
  540.             ('queue', 0, 0)], gtk.gdk.ACTION_COPY)
  541.         self.dests_iconview.connect('drag-data-get', self.dests_iconview_drag_data_get)
  542.         m = gtk.SELECTION_MULTIPLE
  543.         s = gtk.SELECTION_SINGLE
  544.         for name, treeview, selection_mode in ((_('Members of this class'), self.tvClassMembers, m), (_('Others'), self.tvClassNotMembers, m), (_('Members of this class'), np.tvNCMembers, m), (_('Others'), np.tvNCNotMembers, m), (_('Devices'), np.tvNPDevices, s), (_('Connections'), np.tvNPDeviceURIs, s), (_('Makes'), np.tvNPMakes, s), (_('Models'), np.tvNPModels, s), (_('Drivers'), np.tvNPDrivers, s), (_('Downloadable Drivers'), np.tvNPDownloadableDrivers, s), (_('Users'), self.tvPUsers, m)):
  545.             model = gtk.ListStore(str)
  546.             cell = gtk.CellRendererText()
  547.             column = gtk.TreeViewColumn(name, cell, text = 0)
  548.             treeview.set_model(model)
  549.             treeview.append_column(column)
  550.             treeview.get_selection().set_mode(selection_mode)
  551.         
  552.         self.ServerSettingsDialog.connect('response', self.server_settings_response)
  553.         self.PrinterPropertiesDialog.connect('response', self.printer_properties_response)
  554.         col = gtk.TreeViewColumn('', gtk.CellRendererText(), markup = 0)
  555.         self.tvPrinterProperties.append_column(col)
  556.         sel = self.tvPrinterProperties.get_selection()
  557.         sel.connect('changed', self.on_tvPrinterProperties_selection_changed)
  558.         sel.set_mode(gtk.SELECTION_SINGLE)
  559.         opts = [
  560.             options.OptionAlwaysShown('copies', int, 1, self.sbJOCopies, self.btnJOResetCopies),
  561.             options.OptionAlwaysShownSpecial('orientation-requested', int, 3, self.cmbJOOrientationRequested, self.btnJOResetOrientationRequested, combobox_map = [
  562.                 3,
  563.                 4,
  564.                 5,
  565.                 6], special_choice = _('Automatic rotation')),
  566.             options.OptionAlwaysShown('fitplot', bool, False, self.cbJOFitplot, self.btnJOResetFitplot),
  567.             options.OptionAlwaysShown('number-up', int, 1, self.cmbJONumberUp, self.btnJOResetNumberUp, combobox_map = [
  568.                 1,
  569.                 2,
  570.                 4,
  571.                 6,
  572.                 9,
  573.                 16]),
  574.             options.OptionAlwaysShown('number-up-layout', str, 'lrtb', self.cmbJONumberUpLayout, self.btnJOResetNumberUpLayout, combobox_map = [
  575.                 'lrtb',
  576.                 'lrbt',
  577.                 'rltb',
  578.                 'rlbt',
  579.                 'tblr',
  580.                 'tbrl',
  581.                 'btlr',
  582.                 'btrl']),
  583.             options.OptionAlwaysShown('brightness', int, 100, self.sbJOBrightness, self.btnJOResetBrightness),
  584.             options.OptionAlwaysShown('finishings', int, 3, self.cmbJOFinishings, self.btnJOResetFinishings, combobox_map = [
  585.                 3,
  586.                 4,
  587.                 5,
  588.                 6,
  589.                 7,
  590.                 8,
  591.                 9,
  592.                 10,
  593.                 11,
  594.                 12,
  595.                 13,
  596.                 14,
  597.                 20,
  598.                 21,
  599.                 22,
  600.                 23,
  601.                 24,
  602.                 25,
  603.                 26,
  604.                 27,
  605.                 28,
  606.                 29,
  607.                 30,
  608.                 31,
  609.                 50,
  610.                 51,
  611.                 52,
  612.                 53], use_supported = True),
  613.             options.OptionAlwaysShown('job-priority', int, 50, self.sbJOJobPriority, self.btnJOResetJobPriority),
  614.             options.OptionAlwaysShown('media', str, 'A4', self.cmbJOMedia, self.btnJOResetMedia, use_supported = True),
  615.             options.OptionAlwaysShown('sides', str, 'one-sided', self.cmbJOSides, self.btnJOResetSides, combobox_map = [
  616.                 'one-sided',
  617.                 'two-sided-long-edge',
  618.                 'two-sided-short-edge']),
  619.             options.OptionAlwaysShown('job-hold-until', str, 'no-hold', self.cmbJOHoldUntil, self.btnJOResetHoldUntil, use_supported = True),
  620.             options.OptionAlwaysShown('mirror', bool, False, self.cbJOMirror, self.btnJOResetMirror),
  621.             options.OptionAlwaysShown('scaling', int, 100, self.sbJOScaling, self.btnJOResetScaling),
  622.             options.OptionAlwaysShown('saturation', int, 100, self.sbJOSaturation, self.btnJOResetSaturation),
  623.             options.OptionAlwaysShown('hue', int, 0, self.sbJOHue, self.btnJOResetHue),
  624.             options.OptionAlwaysShown('gamma', int, 1000, self.sbJOGamma, self.btnJOResetGamma),
  625.             options.OptionAlwaysShown('cpi', float, 10, self.sbJOCpi, self.btnJOResetCpi),
  626.             options.OptionAlwaysShown('lpi', float, 6, self.sbJOLpi, self.btnJOResetLpi),
  627.             options.OptionAlwaysShown('page-left', int, 0, self.sbJOPageLeft, self.btnJOResetPageLeft),
  628.             options.OptionAlwaysShown('page-right', int, 0, self.sbJOPageRight, self.btnJOResetPageRight),
  629.             options.OptionAlwaysShown('page-top', int, 0, self.sbJOPageTop, self.btnJOResetPageTop),
  630.             options.OptionAlwaysShown('page-bottom', int, 0, self.sbJOPageBottom, self.btnJOResetPageBottom),
  631.             options.OptionAlwaysShown('prettyprint', bool, False, self.cbJOPrettyPrint, self.btnJOResetPrettyPrint),
  632.             options.OptionAlwaysShown('wrap', bool, False, self.cbJOWrap, self.btnJOResetWrap),
  633.             options.OptionAlwaysShown('columns', int, 1, self.sbJOColumns, self.btnJOResetColumns)]
  634.         self.job_options_widgets = { }
  635.         self.job_options_buttons = { }
  636.         for option in opts:
  637.             self.job_options_widgets[option.widget] = option
  638.             self.job_options_buttons[option.button] = option
  639.         
  640.         self.monitor = monitor.Monitor(self, monitor_jobs = False)
  641.         
  642.         try:
  643.             self.populateList()
  644.         except cups.HTTPError:
  645.             (s,) = None
  646.             self.cups = None
  647.             self.setConnected()
  648.             self.populateList()
  649.             show_HTTP_Error(s, self.PrintersWindow)
  650.  
  651.         
  652.         try:
  653.             (max_width, max_height) = (600, 400)
  654.             self.dests_iconview.resize_children()
  655.             (width, height) = self.dests_iconview.size_request()
  656.             if height > max_height:
  657.                 self.dests_iconview.set_size_request(max_width, -1)
  658.                 self.dests_iconview.resize_children()
  659.                 while gtk.events_pending():
  660.                     gtk.main_iteration()
  661.                 (width, height) = self.dests_iconview.size_request()
  662.                 (width, height) = map(min, (width, height), (max_width, max_height))
  663.             
  664.             self.dests_iconview.set_size_request(width, height)
  665.             while gtk.events_pending():
  666.                 gtk.main_iteration()
  667.             (width, height) = self.PrintersWindow.get_size()
  668.             self.dests_iconview.set_size_request(-1, -1)
  669.             self.PrintersWindow.resize(width, height)
  670.         except:
  671.             nonfatalException()
  672.  
  673.         if setup_printer:
  674.             self.device_uri = setup_printer
  675.             self.devid = devid
  676.             self.ppd = None
  677.             
  678.             try:
  679.                 self.on_autodetected_printer_without_driver(None)
  680.             except RuntimeError:
  681.                 pass
  682.             except:
  683.                 None<EXCEPTION MATCH>RuntimeError
  684.             
  685.  
  686.         None<EXCEPTION MATCH>RuntimeError
  687.         if configure_printer:
  688.             
  689.             try:
  690.                 self.display_properties_dialog_for(configure_printer)
  691.                 if print_test_page:
  692.                     self.btnPrintTestPage.clicked()
  693.                 
  694.                 if change_ppd:
  695.                     self.btnChangePPD.clicked()
  696.             except RuntimeError:
  697.                 pass
  698.             except:
  699.                 None<EXCEPTION MATCH>RuntimeError
  700.             
  701.  
  702.         None<EXCEPTION MATCH>RuntimeError
  703.  
  704.     
  705.     def display_properties_dialog_for(self, queue):
  706.         model = self.dests_iconview.get_model()
  707.         iter = model.get_iter_first()
  708.         while iter != None:
  709.             name = unicode(model.get_value(iter, 2))
  710.             if name == queue:
  711.                 path = model.get_path(iter)
  712.                 self.dests_iconview.scroll_to_path(path, True, 0.5, 0.5)
  713.                 self.dests_iconview.set_cursor(path)
  714.                 self.dests_iconview.item_activated(path)
  715.                 break
  716.             
  717.             iter = model.iter_next(iter)
  718.         if iter == None:
  719.             raise RuntimeError
  720.         iter == None
  721.  
  722.     
  723.     def setup_toolbar_for_search_entry(self):
  724.         separator = gtk.SeparatorToolItem()
  725.         separator.set_draw(False)
  726.         self.toolbar.insert(separator, -1)
  727.         self.toolbar.child_set_property(separator, 'expand', True)
  728.         self.search_entry = ToolbarSearchEntry()
  729.         self.search_entry.connect('search', self.on_search_entry_search)
  730.         tool_item = gtk.ToolItem()
  731.         tool_item.add(self.search_entry)
  732.         self.toolbar.insert(tool_item, -1)
  733.         self.toolbar.show_all()
  734.  
  735.     
  736.     def on_search_entry_search(self, UNUSED, text):
  737.         if not text or True:
  738.             pass
  739.         self.ui_manager.get_action('/save-as-group').set_sensitive(False)
  740.         if not text or True:
  741.             pass
  742.         self.ui_manager.get_action('/save-as-search-group').set_sensitive(False)
  743.         self.current_filter_text = text
  744.         self.populateList()
  745.  
  746.     
  747.     def on_groups_pane_item_activated(self, UNUSED, item):
  748.         self.search_entry.clear()
  749.         if isinstance(item, SavedSearchGroupItem):
  750.             crit = item.criteria[0]
  751.             if crit.subject == SearchCriterion.SUBJECT_NAME:
  752.                 self.ui_manager.get_action('/filter-name').activate()
  753.             elif crit.subject == SearchCriterion.SUBJECT_DESC:
  754.                 self.ui_manager.get_action('/filter-description').activate()
  755.             elif crit.subject == SearchCriterion.SUBJECT_LOCATION:
  756.                 self.ui_manager.get_action('/filter-location').activate()
  757.             elif crit.subject == SearchCriterion.SUBJECT_MANUF:
  758.                 self.ui_manager.get_action('/filter-manufacturer').activate()
  759.             else:
  760.                 nonfatalException()
  761.             self.search_entry.set_text(crit.value)
  762.         
  763.         self.current_groups_pane_item = item
  764.         self.populateList()
  765.  
  766.     
  767.     def on_add_to_group_menu_item_activate(self, menuitem, group):
  768.         group.add_queues(self.groups_pane.currently_selected_queues)
  769.  
  770.     
  771.     def update_add_to_group_menu(self):
  772.         for child in self.add_to_group_menu.get_children():
  773.             self.add_to_group_menu.remove(child)
  774.         
  775.         static_groups = self.groups_pane.get_static_groups()
  776.         for group in static_groups:
  777.             item = gtk.MenuItem(group.name, False)
  778.             item.connect('activate', self.on_add_to_group_menu_item_activate, group)
  779.             self.add_to_group_menu.append(item)
  780.         
  781.         if len(static_groups) > 0:
  782.             item = gtk.SeparatorMenuItem()
  783.             self.add_to_group_menu.append(item)
  784.         
  785.         action = self.groups_pane.ui_manager.get_action('/new-group-from-selection')
  786.         item = action.create_menu_item()
  787.         self.add_to_group_menu.append(item)
  788.         self.add_to_group_menu.show_all()
  789.  
  790.     
  791.     def on_groups_pane_items_changed(self, UNUSED):
  792.         if not self.groups_pane_visible:
  793.             self.view_groups.set_active(True)
  794.         
  795.         self.update_add_to_group_menu()
  796.  
  797.     
  798.     def on_filter_criterion_changed(self, UNUSED, selected_action):
  799.         self.current_filter_mode = selected_action.get_name()
  800.         self.populateList()
  801.  
  802.     
  803.     def dests_iconview_item_activated(self, iconview, path):
  804.         model = iconview.get_model()
  805.         iter = model.get_iter(path)
  806.         name = unicode(model.get_value(iter, 2))
  807.         object = model.get_value(iter, 0)
  808.         
  809.         try:
  810.             self.fillPrinterTab(name)
  811.         except cups.IPPError:
  812.             (e, m) = None
  813.             show_IPP_Error(e, m, self.PrintersWindow)
  814.             if e == cups.IPP_SERVICE_UNAVAILABLE:
  815.                 self.cups = None
  816.                 self.setConnected()
  817.                 self.populateList()
  818.             
  819.             return None
  820.             except RuntimeError:
  821.                 return None
  822.             else:
  823.                 self.PrinterPropertiesDialog.set_transient_for(self.PrintersWindow)
  824.                 for button in [
  825.                     self.btnPrinterPropertiesCancel,
  826.                     self.btnPrinterPropertiesOK,
  827.                     self.btnPrinterPropertiesApply]:
  828.                     if object.discovered:
  829.                         button.hide()
  830.                         continue
  831.                     button.show()
  832.                 
  833.  
  834.         if object.discovered:
  835.             self.btnPrinterPropertiesClose.show()
  836.         else:
  837.             self.btnPrinterPropertiesClose.hide()
  838.         self.setDataButtonState()
  839.         treeview = self.tvPrinterProperties
  840.         treeview.set_cursor((0,))
  841.         host = CUPS_server_hostname()
  842.         self.PrinterPropertiesDialog.set_title(_("Printer Properties - '%s' on %s") % (name, host))
  843.         self.PrinterPropertiesDialog.set_focus_on_map(self.focus_on_map)
  844.         self.PrinterPropertiesDialog.show()
  845.  
  846.     
  847.     def printer_properties_response(self, dialog, response):
  848.         if response == gtk.RESPONSE_REJECT:
  849.             message = _('There are conflicting options.\nChanges can only be applied after\nthese conflicts are resolved.')
  850.             message += '\n\n'
  851.             for option in self.conflicts:
  852.                 message += option.option.text + '\n'
  853.             
  854.             dialog = gtk.MessageDialog(self.PrinterPropertiesDialog, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, message)
  855.             dialog.run()
  856.             dialog.destroy()
  857.             return None
  858.         if response == gtk.RESPONSE_OK or response == gtk.RESPONSE_APPLY:
  859.             success = self.save_printer(self.printer)
  860.         
  861.         if response == gtk.RESPONSE_APPLY:
  862.             
  863.             try:
  864.                 self.fillPrinterTab(self.printer.name)
  865.             except:
  866.                 pass
  867.  
  868.             self.setDataButtonState()
  869.         
  870.         if response == gtk.RESPONSE_OK or not success or response == gtk.RESPONSE_CANCEL:
  871.             dialog.hide()
  872.         
  873.  
  874.     
  875.     def dests_iconview_selection_changed(self, iconview):
  876.         self.updating_widgets = True
  877.         paths = iconview.get_selected_items()
  878.         any_disabled = False
  879.         any_enabled = False
  880.         any_discovered = False
  881.         any_shared = False
  882.         any_unshared = False
  883.         self.groups_pane.currently_selected_queues = []
  884.         model = iconview.get_model()
  885.         for path in paths:
  886.             iter = model.get_iter(path)
  887.             object = model.get_value(iter, 0)
  888.             name = unicode(model.get_value(iter, 2))
  889.             self.groups_pane.currently_selected_queues.append(name)
  890.             if object.discovered:
  891.                 any_discovered = True
  892.             
  893.             if object.enabled:
  894.                 any_enabled = True
  895.             else:
  896.                 any_disabled = True
  897.             if object.is_shared:
  898.                 any_shared = True
  899.                 continue
  900.             any_unshared = True
  901.         
  902.         n = len(paths)
  903.         self.groups_pane.ui_manager.get_action('/new-group-from-selection').set_sensitive(n > 0)
  904.         self.ui_manager.get_action('/edit-printer').set_sensitive(n == 1)
  905.         self.ui_manager.get_action('/copy-printer').set_sensitive(n == 1)
  906.         if n == 1:
  907.             pass
  908.         self.ui_manager.get_action('/rename-printer').set_sensitive(not any_discovered)
  909.         userdef = userdefault.UserDefaultPrinter().get()
  910.         if (n != 1 or userdef == None) and self.default_printer == name:
  911.             set_default_sensitivity = False
  912.         else:
  913.             set_default_sensitivity = True
  914.         self.ui_manager.get_action('/set-default-printer').set_sensitive(set_default_sensitivity)
  915.         action = self.ui_manager.get_action('/enable-printer')
  916.         if n > 0:
  917.             pass
  918.         action.set_sensitive(not any_discovered)
  919.         for widget in action.get_proxies():
  920.             if isinstance(widget, gtk.CheckMenuItem):
  921.                 if n > 1 and any_enabled:
  922.                     pass
  923.                 widget.set_inconsistent(any_disabled)
  924.                 continue
  925.         
  926.         if not any_discovered:
  927.             pass
  928.         action.set_active(not any_disabled)
  929.         action = self.ui_manager.get_action('/share-printer')
  930.         if n > 0:
  931.             pass
  932.         action.set_sensitive(not any_discovered)
  933.         for widget in action.get_proxies():
  934.             if isinstance(widget, gtk.CheckMenuItem):
  935.                 if n > 1 and any_shared:
  936.                     pass
  937.                 widget.set_inconsistent(any_unshared)
  938.                 continue
  939.         
  940.         if not any_discovered:
  941.             pass
  942.         action.set_active(not any_unshared)
  943.         if n > 0:
  944.             pass
  945.         self.ui_manager.get_action('/delete-printer').set_sensitive(not any_discovered)
  946.         self.ui_manager.get_action('/create-class').set_sensitive(n > 1)
  947.         self.ui_manager.get_action('/add-to-group').set_sensitive(n > 0)
  948.         self.updating_widgets = False
  949.  
  950.     
  951.     def dests_iconview_popup_menu(self, iconview):
  952.         self.printer_context_menu.popup(None, None, None, 0, 0x0L)
  953.  
  954.     
  955.     def dests_iconview_button_press_event(self, iconview, event):
  956.         if event.button > 1:
  957.             click_path = iconview.get_path_at_pos(int(event.x), int(event.y))
  958.             paths = iconview.get_selected_items()
  959.             if click_path == None:
  960.                 iconview.unselect_all()
  961.             elif click_path not in paths:
  962.                 iconview.unselect_all()
  963.                 iconview.select_path(click_path)
  964.                 cells = iconview.get_cells()
  965.                 for cell in cells:
  966.                     if type(cell) == gtk.CellRendererText:
  967.                         break
  968.                         continue
  969.                 
  970.                 iconview.set_cursor(click_path, cell)
  971.             
  972.             self.printer_context_menu.popup(None, None, None, event.button, event.time)
  973.         
  974.         return False
  975.  
  976.     
  977.     def dests_iconview_key_press_event(self, iconview, event):
  978.         modifiers = gtk.accelerator_get_default_mod_mask()
  979.         if (event.keyval == gtk.keysyms.BackSpace and event.keyval == gtk.keysyms.Delete or event.keyval == gtk.keysyms.KP_Delete) and event.state & modifiers == 0:
  980.             self.ui_manager.get_action('/delete-printer').activate()
  981.             return True
  982.         if event.keyval == gtk.keysyms.F2 and event.state & modifiers == 0:
  983.             self.ui_manager.get_action('/rename-printer').activate()
  984.             return True
  985.         return False
  986.  
  987.     
  988.     def dests_iconview_drag_data_get(self, iconview, context, selection_data, info, timestamp):
  989.         if info == 0:
  990.             model = iconview.get_model()
  991.             paths = iconview.get_selected_items()
  992.             selected_printer_names = ''
  993.             for path in paths:
  994.                 selected_printer_names += model.get_value(model.get_iter(path), 2) + '\n'
  995.             
  996.             if len(selected_printer_names) > 0:
  997.                 selection_data.set('queue', 8, selected_printer_names)
  998.             
  999.         else:
  1000.             nonfatalException()
  1001.  
  1002.     
  1003.     def on_server_settings_activate(self, menuitem):
  1004.         
  1005.         try:
  1006.             self.fillServerTab()
  1007.         except cups.IPPError:
  1008.             return None
  1009.  
  1010.         self.ServerSettingsDialog.set_transient_for(self.PrintersWindow)
  1011.         self.ServerSettingsDialog.show()
  1012.  
  1013.     
  1014.     def server_settings_response(self, dialog, response):
  1015.         if response == gtk.RESPONSE_OK:
  1016.             if not self.save_serversettings():
  1017.                 dialog.hide()
  1018.             
  1019.         elif response == gtk.RESPONSE_YES:
  1020.             
  1021.             try:
  1022.                 AdvancedServerSettingsDialog(self.cups, dialog, self.on_adv_server_settings_apply)
  1023.             return None
  1024.  
  1025.         else:
  1026.             dialog.hide()
  1027.  
  1028.     
  1029.     def on_adv_server_settings_apply(self):
  1030.         
  1031.         try:
  1032.             self.fillServerTab()
  1033.         except cups.IPPError:
  1034.             dialog.hide()
  1035.  
  1036.  
  1037.     
  1038.     def busy(self, win = None):
  1039.         
  1040.         try:
  1041.             if not win:
  1042.                 win = self.PrintersWindow
  1043.             
  1044.             gdkwin = win.window
  1045.             if gdkwin:
  1046.                 gdkwin.set_cursor(busy_cursor)
  1047.                 while gtk.events_pending():
  1048.                     gtk.main_iteration()
  1049.         except:
  1050.             nonfatalException()
  1051.  
  1052.  
  1053.     
  1054.     def ready(self, win = None):
  1055.         
  1056.         try:
  1057.             if not win:
  1058.                 win = self.PrintersWindow
  1059.             
  1060.             gdkwin = win.window
  1061.             if gdkwin:
  1062.                 gdkwin.set_cursor(ready_cursor)
  1063.                 while gtk.events_pending():
  1064.                     gtk.main_iteration()
  1065.         except:
  1066.             nonfatalException()
  1067.  
  1068.  
  1069.     
  1070.     def setConnected(self):
  1071.         connected = bool(self.cups)
  1072.         host = CUPS_server_hostname()
  1073.         self.PrintersWindow.set_title(_('Printer configuration - %s') % host)
  1074.         self.PrintersWindow.set_focus_on_map(self.focus_on_map)
  1075.         if connected:
  1076.             status_msg = _('Connected to %s') % host
  1077.         else:
  1078.             status_msg = _('Not connected')
  1079.         self.statusbarMain.push(self.status_context_id, status_msg)
  1080.         for widget in (self.btnNew, self.new_printer, self.new_class, self.chkServerBrowse, self.chkServerShare, self.chkServerRemoteAdmin, self.chkServerAllowCancelAll, self.chkServerLogDebug, self.server_settings_menu_entry):
  1081.             widget.set_sensitive(connected)
  1082.         
  1083.         sharing = self.chkServerShare.get_active()
  1084.         self.chkServerShareAny.set_sensitive(sharing)
  1085.         
  1086.         try:
  1087.             del self.server_settings
  1088.         except:
  1089.             pass
  1090.  
  1091.  
  1092.     
  1093.     def getServers(self):
  1094.         self.servers.discard(None)
  1095.         known_servers = list(self.servers)
  1096.         known_servers.sort()
  1097.         return known_servers
  1098.  
  1099.     
  1100.     def populateList(self, prompt_allowed = True):
  1101.         selected_printers = set()
  1102.         paths = self.dests_iconview.get_selected_items()
  1103.         model = self.dests_iconview.get_model()
  1104.         for path in paths:
  1105.             iter = model.get_iter(path)
  1106.             name = unicode(model.get_value(iter, 2))
  1107.             selected_printers.add(name)
  1108.         
  1109.         if self.cups:
  1110.             self.cups._set_prompt_allowed(prompt_allowed)
  1111.             self.cups._begin_operation(_('obtaining queue details'))
  1112.             
  1113.             try:
  1114.                 self.printers = cupshelpers.getPrinters(self.cups)
  1115.                 self.default_printer = self.cups.getDefault()
  1116.             except cups.IPPError:
  1117.                 (e, m) = None
  1118.                 show_IPP_Error(e, m, self.PrintersWindow)
  1119.                 self.printers = { }
  1120.                 self.default_printer = None
  1121.  
  1122.             self.cups._end_operation()
  1123.             self.cups._set_prompt_allowed(True)
  1124.         else:
  1125.             self.printers = { }
  1126.             self.default_printer = None
  1127.         for name, printer in self.printers.iteritems():
  1128.             self.servers.add(printer.getServer())
  1129.         
  1130.         userdef = userdefault.UserDefaultPrinter().get()
  1131.         local_printers = []
  1132.         local_classes = []
  1133.         remote_printers = []
  1134.         remote_classes = []
  1135.         if isinstance(self.current_groups_pane_item, AllPrintersItem) or isinstance(self.current_groups_pane_item, SavedSearchGroupItem):
  1136.             delete_action = self.ui_manager.get_action('/delete-printer')
  1137.             delete_action.set_properties(label = None)
  1138.             printers_set = self.printers
  1139.         elif isinstance(self.current_groups_pane_item, FavouritesItem):
  1140.             printers_set = { }
  1141.         elif isinstance(self.current_groups_pane_item, StaticGroupItem):
  1142.             delete_action = self.ui_manager.get_action('/delete-printer')
  1143.             delete_action.set_properties(label = _('Remove from Group'))
  1144.             printers_set = { }
  1145.             deleted_printers = []
  1146.             for printer_name in self.current_groups_pane_item.printer_queues:
  1147.                 
  1148.                 try:
  1149.                     printer = self.printers[printer_name]
  1150.                     printers_set[printer_name] = printer
  1151.                 continue
  1152.                 except KeyError:
  1153.                     deleted_printers.append(printer_name)
  1154.                     continue
  1155.                 
  1156.  
  1157.             
  1158.             self.current_groups_pane_item.remove_queues(deleted_printers)
  1159.         else:
  1160.             printers_set = self.printers
  1161.             nonfatalException()
  1162.         if len(self.current_filter_text) > 0:
  1163.             printers_subset = { }
  1164.             pattern = re.compile(self.current_filter_text, re.I)
  1165.             if self.current_filter_mode == 'filter-name':
  1166.                 for name in printers_set.keys():
  1167.                     if pattern.search(name) != None:
  1168.                         printers_subset[name] = printers_set[name]
  1169.                         continue
  1170.                 
  1171.             elif self.current_filter_mode == 'filter-description':
  1172.                 for name, printer in printers_set.iteritems():
  1173.                     if pattern.search(printer.info) != None:
  1174.                         printers_subset[name] = printers_set[name]
  1175.                         continue
  1176.                 
  1177.             elif self.current_filter_mode == 'filter-location':
  1178.                 for name, printer in printers_set.iteritems():
  1179.                     if pattern.search(printer.location) != None:
  1180.                         printers_subset[name] = printers_set[name]
  1181.                         continue
  1182.                 
  1183.             elif self.current_filter_mode == 'filter-manufacturer':
  1184.                 for name, printer in printers_set.iteritems():
  1185.                     if pattern.search(printer.make_and_model) != None:
  1186.                         printers_subset[name] = printers_set[name]
  1187.                         continue
  1188.                 
  1189.             else:
  1190.                 nonfatalException()
  1191.             printers_set = printers_subset
  1192.         
  1193.         if not self.view_discovered_printers.get_active():
  1194.             printers_subset = { }
  1195.             for name, printer in printers_set.iteritems():
  1196.                 if not printer.discovered:
  1197.                     printers_subset[name] = printer
  1198.                     continue
  1199.             
  1200.             printers_set = printers_subset
  1201.         
  1202.         for name, printer in printers_set.iteritems():
  1203.             if printer.remote:
  1204.                 if printer.is_class:
  1205.                     remote_classes.append(name)
  1206.                 else:
  1207.                     remote_printers.append(name)
  1208.             printer.is_class
  1209.             if printer.is_class:
  1210.                 local_classes.append(name)
  1211.                 continue
  1212.             local_printers.append(name)
  1213.         
  1214.         local_printers.sort()
  1215.         local_classes.sort()
  1216.         remote_printers.sort()
  1217.         remote_classes.sort()
  1218.         self.mainlist.clear()
  1219.         PRINTER_TYPE = {
  1220.             'discovered-printer': (_('Network printer (discovered)'), 'i-network-printer'),
  1221.             'discovered-class': (_('Network class (discovered)'), 'i-network-printer'),
  1222.             'local-printer': (_('Printer'), 'gnome-dev-printer'),
  1223.             'local-fax': (_('Fax'), 'gnome-dev-printer'),
  1224.             'local-class': (_('Class'), 'gnome-dev-printer'),
  1225.             'ipp-printer': (_('Network printer'), 'i-network-printer'),
  1226.             'smb-printer': (_('Network print share'), 'gnome-dev-printer'),
  1227.             'network-printer': (_('Network printer'), 'i-network-printer') }
  1228.         theme = gtk.icon_theme_get_default()
  1229.         for printers in (local_printers, local_classes, remote_printers, remote_classes):
  1230.             if not printers:
  1231.                 continue
  1232.             
  1233.             for name in printers:
  1234.                 type = 'local-printer'
  1235.                 object = printers_set[name]
  1236.                 if object.discovered:
  1237.                     if object.is_class:
  1238.                         type = 'discovered-class'
  1239.                     else:
  1240.                         type = 'discovered-printer'
  1241.                 elif object.is_class:
  1242.                     type = 'local-class'
  1243.                 else:
  1244.                     (scheme, rest) = urllib.splittype(object.device_uri)
  1245.                     if scheme == 'ipp':
  1246.                         type = 'ipp-printer'
  1247.                     elif scheme == 'smb':
  1248.                         type = 'smb-printer'
  1249.                     elif scheme == 'hpfax':
  1250.                         type = 'local-fax'
  1251.                     elif scheme in ('socket', 'lpd'):
  1252.                         type = 'network-printer'
  1253.                     
  1254.                 (tip, icon) = PRINTER_TYPE[type]
  1255.                 (w, h) = gtk.icon_size_lookup(gtk.ICON_SIZE_DIALOG)
  1256.                 
  1257.                 try:
  1258.                     pixbuf = theme.load_icon(icon, w, 0)
  1259.                 except gobject.GError:
  1260.                     pixbuf = None
  1261.                     for p in [
  1262.                         iconpath,
  1263.                         'icons/']:
  1264.                         
  1265.                         try:
  1266.                             pixbuf = gtk.gdk.pixbuf_new_from_file('%s%s.png' % (p, icon))
  1267.                         continue
  1268.                         except gobject.GError:
  1269.                             continue
  1270.                         
  1271.  
  1272.                     
  1273.                     if pixbuf == None:
  1274.                         
  1275.                         try:
  1276.                             pixbuf = theme.load_icon('printer', w, 0)
  1277.                         pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
  1278.                         pixbuf.fill(0)
  1279.  
  1280.                     
  1281.                 except:
  1282.                     None<EXCEPTION MATCH>gobject.GError
  1283.  
  1284.                 emblem = None
  1285.                 if name == self.default_printer:
  1286.                     emblem = 'emblem-default'
  1287.                 elif name == userdef:
  1288.                     emblem = 'emblem-favorite'
  1289.                 
  1290.                 if emblem:
  1291.                     (w, h) = gtk.icon_size_lookup(gtk.ICON_SIZE_DIALOG)
  1292.                     default_emblem = theme.load_icon(emblem, w / 2, 0)
  1293.                     copy = pixbuf.copy()
  1294.                     default_emblem.composite(copy, 0, 0, copy.get_width(), copy.get_height(), 0, 0, 1, 1, gtk.gdk.INTERP_NEAREST, 255)
  1295.                     pixbuf = copy
  1296.                 
  1297.                 self.mainlist.append(row = [
  1298.                     object,
  1299.                     pixbuf,
  1300.                     name,
  1301.                     tip])
  1302.             
  1303.         
  1304.         model = self.dests_iconview.get_model()
  1305.         
  1306.         def maybe_select(model, path, iter):
  1307.             name = unicode(model.get_value(iter, 2))
  1308.             if name in selected_printers:
  1309.                 self.dests_iconview.select_path(path)
  1310.             
  1311.  
  1312.         model.foreach(maybe_select)
  1313.         if self.printer != None and self.printer.name not in self.printers.keys():
  1314.             self.PrinterPropertiesDialog.response(gtk.RESPONSE_CANCEL)
  1315.         
  1316.  
  1317.     
  1318.     def on_connect_servername_changed(self, widget):
  1319.         self.btnConnect.set_sensitive(len(widget.get_active_text()) > 0)
  1320.  
  1321.     
  1322.     def on_connect_activate(self, widget):
  1323.         servers = self.getServers()
  1324.         if not self.printer or self.printer.getServer():
  1325.             pass
  1326.         current_server = cups.getServer()
  1327.         store = gtk.ListStore(gobject.TYPE_STRING)
  1328.         self.cmbServername.set_model(store)
  1329.         for server in servers:
  1330.             self.cmbServername.append_text(server)
  1331.         
  1332.         self.cmbServername.show()
  1333.         self.cmbServername.child.set_text(current_server)
  1334.         self.chkEncrypted.set_active(cups.getEncryption() == cups.HTTP_ENCRYPT_ALWAYS)
  1335.         self.cmbServername.child.set_activates_default(True)
  1336.         self.cmbServername.grab_focus()
  1337.         self.ConnectDialog.set_transient_for(self.PrintersWindow)
  1338.         response = self.ConnectDialog.run()
  1339.         self.ConnectDialog.hide()
  1340.         if response != gtk.RESPONSE_OK:
  1341.             return None
  1342.         if self.chkEncrypted.get_active():
  1343.             cups.setEncryption(cups.HTTP_ENCRYPT_ALWAYS)
  1344.         else:
  1345.             cups.setEncryption(cups.HTTP_ENCRYPT_IF_REQUESTED)
  1346.         self.connect_encrypt = cups.getEncryption()
  1347.         servername = self.cmbServername.child.get_text()
  1348.         self.lblConnecting.set_markup(_('<i>Opening connection to %s</i>') % servername)
  1349.         self.newPrinterGUI.dropPPDs()
  1350.         self.ConnectingDialog.set_transient_for(self.PrintersWindow)
  1351.         self.ConnectingDialog.show()
  1352.         gobject.timeout_add(40, self.update_connecting_pbar)
  1353.         self.connect_server = servername
  1354.         cups.setServer(self.connect_server)
  1355.         cups.setUser('')
  1356.         self.connect_user = cups.getUser()
  1357.         self.connect_thread = thread.start_new_thread(self.connect, (self.PrintersWindow,))
  1358.  
  1359.     
  1360.     def update_connecting_pbar(self):
  1361.         if not self.ConnectingDialog.get_property('visible'):
  1362.             return False
  1363.         self.pbarConnecting.pulse()
  1364.         return True
  1365.  
  1366.     
  1367.     def on_connectingdialog_delete(self, widget, event):
  1368.         self.on_cancel_connect_clicked(widget)
  1369.         return True
  1370.  
  1371.     
  1372.     def on_cancel_connect_clicked(self, widget):
  1373.         """
  1374.         Stop connection to new server
  1375.         (Doesn't really stop but sets flag for the connecting thread to
  1376.         ignore the connection)
  1377.         """
  1378.         self.connect_thread = None
  1379.         self.ConnectingDialog.hide()
  1380.  
  1381.     
  1382.     def connect(self, parent = None):
  1383.         '''
  1384.         Open a connection to a new server. Is executed in a separate thread!
  1385.         '''
  1386.         cups.setUser(self.connect_user)
  1387.         if self.connect_server[0] == '/':
  1388.             
  1389.             try:
  1390.                 connection = cups.Connection(host = self.connect_server, encryption = self.connect_encrypt)
  1391.                 del connection
  1392.             except RuntimeError:
  1393.                 cups.setServer('localhost')
  1394.             except:
  1395.                 None<EXCEPTION MATCH>RuntimeError
  1396.                 nonfatalException()
  1397.             
  1398.  
  1399.         None<EXCEPTION MATCH>RuntimeError
  1400.         
  1401.         try:
  1402.             connection = authconn.Connection(parent, host = self.connect_server, encryption = self.connect_encrypt)
  1403.             self.newPrinterGUI.dropPPDs()
  1404.         except RuntimeError:
  1405.             s = None
  1406.             if self.connect_thread != thread.get_ident():
  1407.                 return None
  1408.             gtk.gdk.threads_enter()
  1409.             self.ConnectingDialog.hide()
  1410.             show_IPP_Error(None, s, parent)
  1411.             gtk.gdk.threads_leave()
  1412.             return None
  1413.             self.connect_thread != thread.get_ident()
  1414.             except cups.IPPError:
  1415.                 (e, s) = None
  1416.                 if self.connect_thread != thread.get_ident():
  1417.                     return None
  1418.                 gtk.gdk.threads_enter()
  1419.                 self.ConnectingDialog.hide()
  1420.                 show_IPP_Error(e, s, parent)
  1421.                 gtk.gdk.threads_leave()
  1422.                 return None
  1423.                 self.connect_thread != thread.get_ident()
  1424.                 nonfatalException()
  1425.             
  1426.  
  1427.         if self.connect_thread != thread.get_ident():
  1428.             return None
  1429.         gtk.gdk.threads_enter()
  1430.         
  1431.         try:
  1432.             self.ConnectingDialog.hide()
  1433.             self.cups = connection
  1434.             self.setConnected()
  1435.             self.populateList()
  1436.         except cups.HTTPError:
  1437.             self.connect_thread != thread.get_ident()
  1438.             (s,) = self.connect_thread != thread.get_ident()
  1439.             None<EXCEPTION MATCH>cups.IPPError
  1440.             self.cups = None
  1441.             self.setConnected()
  1442.             self.populateList()
  1443.             show_HTTP_Error(s, parent)
  1444.         except:
  1445.             self.connect_thread != thread.get_ident()
  1446.             None<EXCEPTION MATCH>cups.IPPError
  1447.             nonfatalException()
  1448.  
  1449.         gtk.gdk.threads_leave()
  1450.  
  1451.     
  1452.     def reconnect(self):
  1453.         '''Reconnect to CUPS after the server has reloaded.'''
  1454.         attempt = 1
  1455.         while attempt <= 5:
  1456.             
  1457.             try:
  1458.                 time.sleep(1)
  1459.                 self.cups._connect()
  1460.             continue
  1461.             except RuntimeError:
  1462.                 attempt += 1
  1463.                 continue
  1464.             
  1465.  
  1466.             None<EXCEPTION MATCH>RuntimeError
  1467.  
  1468.     
  1469.     def on_btnCancelConnect_clicked(self, widget):
  1470.         '''Close Connect dialog'''
  1471.         self.ConnectWindow.hide()
  1472.  
  1473.     
  1474.     def on_btnRefresh_clicked(self, button):
  1475.         if self.cups == None:
  1476.             
  1477.             try:
  1478.                 self.cups = authconn.Connection(self.PrintersWindow)
  1479.             except RuntimeError:
  1480.                 pass
  1481.  
  1482.             self.setConnected()
  1483.         
  1484.         self.populateList()
  1485.  
  1486.     
  1487.     def on_printer_changed(self, widget):
  1488.         if isinstance(widget, gtk.CheckButton):
  1489.             value = widget.get_active()
  1490.         elif isinstance(widget, gtk.Entry):
  1491.             value = widget.get_text()
  1492.         elif isinstance(widget, gtk.RadioButton):
  1493.             value = widget.get_active()
  1494.         elif isinstance(widget, gtk.ComboBox):
  1495.             model = widget.get_model()
  1496.             iter = widget.get_active_iter()
  1497.             value = model.get_value(iter, 1)
  1498.         else:
  1499.             raise ValueError, 'Widget type not supported (yet)'
  1500.         p = isinstance(widget, gtk.CheckButton).printer
  1501.         old_values = {
  1502.             self.entPDescription: p.info,
  1503.             self.entPLocation: p.location,
  1504.             self.entPDevice: p.device_uri,
  1505.             self.chkPEnabled: p.enabled,
  1506.             self.chkPAccepting: not (p.rejecting),
  1507.             self.chkPShared: p.is_shared,
  1508.             self.cmbPStartBanner: p.job_sheet_start,
  1509.             self.cmbPEndBanner: p.job_sheet_end,
  1510.             self.cmbPErrorPolicy: p.error_policy,
  1511.             self.cmbPOperationPolicy: p.op_policy,
  1512.             self.rbtnPAllow: p.default_allow }
  1513.         old_value = old_values[widget]
  1514.         if old_value == value:
  1515.             self.changed.discard(widget)
  1516.         else:
  1517.             self.changed.add(widget)
  1518.         self.setDataButtonState()
  1519.  
  1520.     
  1521.     def option_changed(self, option):
  1522.         if option.is_changed():
  1523.             self.changed.add(option)
  1524.         else:
  1525.             self.changed.discard(option)
  1526.         if option.conflicts:
  1527.             self.conflicts.add(option)
  1528.         else:
  1529.             self.conflicts.discard(option)
  1530.         self.setDataButtonState()
  1531.         if self.option_manualfeed and self.option_inputslot and option == self.option_manualfeed:
  1532.             if option.get_current_value() == 'True':
  1533.                 self.option_inputslot.disable()
  1534.             else:
  1535.                 self.option_inputslot.enable()
  1536.         
  1537.  
  1538.     
  1539.     def getPUsers(self):
  1540.         '''return list of usernames from the GUI'''
  1541.         model = self.tvPUsers.get_model()
  1542.         result = []
  1543.         (model.foreach,)((lambda model, path, iter: result.append(model.get(iter, 0)[0])))
  1544.         result.sort()
  1545.         return result
  1546.  
  1547.     
  1548.     def setPUsers(self, users):
  1549.         '''write list of usernames inot the GUI'''
  1550.         model = self.tvPUsers.get_model()
  1551.         model.clear()
  1552.         for user in users:
  1553.             model.append((user,))
  1554.         
  1555.         self.on_entPUser_changed(self.entPUser)
  1556.         self.on_tvPUsers_cursor_changed(self.tvPUsers)
  1557.  
  1558.     
  1559.     def checkPUsersChanged(self):
  1560.         '''check if users in GUI and printer are different
  1561.         and set self.changed'''
  1562.         if self.getPUsers() != self.printer.except_users:
  1563.             self.changed.add(self.tvPUsers)
  1564.         else:
  1565.             self.changed.discard(self.tvPUsers)
  1566.         self.on_tvPUsers_cursor_changed(self.tvPUsers)
  1567.         self.setDataButtonState()
  1568.  
  1569.     
  1570.     def on_btnPAddUser_clicked(self, button):
  1571.         user = self.entPUser.get_text()
  1572.         if user:
  1573.             self.tvPUsers.get_model().insert(0, (user,))
  1574.             self.entPUser.set_text('')
  1575.         
  1576.         self.checkPUsersChanged()
  1577.  
  1578.     
  1579.     def on_btnPDelUser_clicked(self, button):
  1580.         (model, rows) = self.tvPUsers.get_selection().get_selected_rows()
  1581.         rows = [ gtk.TreeRowReference(model, row) for row in rows ]
  1582.         for row in rows:
  1583.             path = row.get_path()
  1584.             iter = model.get_iter(path)
  1585.             model.remove(iter)
  1586.         
  1587.         self.checkPUsersChanged()
  1588.  
  1589.     
  1590.     def on_entPUser_changed(self, widget):
  1591.         self.btnPAddUser.set_sensitive(bool(widget.get_text()))
  1592.  
  1593.     
  1594.     def on_tvPUsers_cursor_changed(self, widget):
  1595.         (model, rows) = widget.get_selection().get_selected_rows()
  1596.         self.btnPDelUser.set_sensitive(bool(rows))
  1597.  
  1598.     
  1599.     def on_job_option_reset(self, button):
  1600.         option = self.job_options_buttons[button]
  1601.         option.reset()
  1602.         if self.server_side_options.has_key(option.name):
  1603.             del self.server_side_options[option.name]
  1604.         
  1605.         if option.is_changed():
  1606.             self.changed.add(option)
  1607.         else:
  1608.             self.changed.discard(option)
  1609.         self.setDataButtonState()
  1610.  
  1611.     
  1612.     def on_job_option_changed(self, widget):
  1613.         if not self.printer:
  1614.             return None
  1615.         option = self.job_options_widgets[widget]
  1616.         option.changed()
  1617.         if option.is_changed():
  1618.             self.server_side_options[option.name] = option
  1619.             self.changed.add(option)
  1620.         elif self.server_side_options.has_key(option.name):
  1621.             del self.server_side_options[option.name]
  1622.         
  1623.         self.changed.discard(option)
  1624.         self.setDataButtonState()
  1625.  
  1626.     
  1627.     def draw_other_job_options(self, editable = True):
  1628.         n = len(self.other_job_options)
  1629.         if n == 0:
  1630.             self.tblJOOther.hide_all()
  1631.             return None
  1632.         self.tblJOOther.resize(n, 3)
  1633.         children = self.tblJOOther.get_children()
  1634.         for child in children:
  1635.             self.tblJOOther.remove(child)
  1636.         
  1637.         i = 0
  1638.         for opt in self.other_job_options:
  1639.             self.tblJOOther.attach(opt.label, 0, 1, i, i + 1, xoptions = gtk.FILL, yoptions = gtk.FILL)
  1640.             opt.label.set_alignment(0, 0.5)
  1641.             self.tblJOOther.attach(opt.selector, 1, 2, i, i + 1, xoptions = gtk.FILL, yoptions = 0)
  1642.             opt.selector.set_sensitive(editable)
  1643.             btn = gtk.Button(stock = 'gtk-remove')
  1644.             btn.connect('clicked', self.on_btnJOOtherRemove_clicked)
  1645.             btn.set_data('pyobject', opt)
  1646.             btn.set_sensitive(editable)
  1647.             self.tblJOOther.attach(btn, 2, 3, i, i + 1, xoptions = 0, yoptions = 0)
  1648.             i += 1
  1649.         
  1650.         self.tblJOOther.show_all()
  1651.  
  1652.     
  1653.     def add_job_option(self, name, value = '', supported = '', is_new = True, editable = True):
  1654.         option = options.OptionWidget(name, value, supported, self.option_changed)
  1655.         option.is_new = is_new
  1656.         self.other_job_options.append(option)
  1657.         self.draw_other_job_options(editable = editable)
  1658.         self.server_side_options[name] = option
  1659.         if name in self.changed:
  1660.             option.is_new = False
  1661.         
  1662.         self.changed.add(option)
  1663.         self.setDataButtonState()
  1664.         if is_new:
  1665.             option.selector.grab_focus()
  1666.         
  1667.  
  1668.     
  1669.     def on_btnJOOtherRemove_clicked(self, button):
  1670.         option = button.get_data('pyobject')
  1671.         self.other_job_options.remove(option)
  1672.         self.draw_other_job_options()
  1673.         if option.is_new:
  1674.             self.changed.discard(option)
  1675.         else:
  1676.             self.changed.add(option.name)
  1677.         del self.server_side_options[option.name]
  1678.         self.setDataButtonState()
  1679.  
  1680.     
  1681.     def on_btnNewJobOption_clicked(self, button):
  1682.         name = self.entNewJobOption.get_text()
  1683.         self.add_job_option(name)
  1684.         self.tblJOOther.show_all()
  1685.         self.entNewJobOption.set_text('')
  1686.         self.btnNewJobOption.set_sensitive(False)
  1687.         self.setDataButtonState()
  1688.  
  1689.     
  1690.     def on_entNewJobOption_changed(self, widget):
  1691.         text = self.entNewJobOption.get_text()
  1692.         if len(text) > 0:
  1693.             pass
  1694.         active = text not in self.server_side_options
  1695.         self.btnNewJobOption.set_sensitive(active)
  1696.  
  1697.     
  1698.     def on_entNewJobOption_activate(self, widget):
  1699.         self.on_btnNewJobOption_clicked(widget)
  1700.  
  1701.     
  1702.     def setDataButtonState(self):
  1703.         
  1704.         try:
  1705.             if self.ppd and not bool(self.changed) and self.printer.enabled:
  1706.                 pass
  1707.             possible = not (self.printer.rejecting)
  1708.             self.btnPrintTestPage.set_sensitive(possible)
  1709.             commands = self.printer.type & cups.CUPS_PRINTER_COMMANDS != 0
  1710.             if commands:
  1711.                 pass
  1712.             self.btnSelfTest.set_sensitive(possible)
  1713.             if commands:
  1714.                 pass
  1715.             self.btnCleanHeads.set_sensitive(possible)
  1716.         except:
  1717.             pass
  1718.  
  1719.         installablebold = False
  1720.         optionsbold = False
  1721.         if self.conflicts:
  1722.             debugprint('Conflicts detected')
  1723.             self.btnConflict.show()
  1724.             for option in self.conflicts:
  1725.                 if option.tab_label == self.lblPInstallOptions:
  1726.                     installablebold = True
  1727.                     continue
  1728.                 optionsbold = True
  1729.             
  1730.         else:
  1731.             self.btnConflict.hide()
  1732.         installabletext = _('Installable Options')
  1733.         optionstext = _('Printer Options')
  1734.         if installablebold:
  1735.             installabletext = '<b>%s</b>' % installabletext
  1736.         
  1737.         if optionsbold:
  1738.             optionstext = '<b>%s</b>' % optionstext
  1739.         
  1740.         self.lblPInstallOptions.set_markup(installabletext)
  1741.         self.lblPOptions.set_markup(optionstext)
  1742.         store = self.tvPrinterProperties.get_model()
  1743.         if store:
  1744.             for n in range(self.ntbkPrinter.get_n_pages()):
  1745.                 page = self.ntbkPrinter.get_nth_page(n)
  1746.                 label = self.ntbkPrinter.get_tab_label(page)
  1747.                 
  1748.                 try:
  1749.                     if label == self.lblPInstallOptions:
  1750.                         iter = store.get_iter((n,))
  1751.                         store.set_value(iter, 0, installabletext)
  1752.                     elif label == self.lblPOptions:
  1753.                         iter = store.get_iter((n,))
  1754.                         store.set_value(iter, 0, optionstext)
  1755.                 continue
  1756.                 except ValueError:
  1757.                     continue
  1758.                 
  1759.  
  1760.             
  1761.         
  1762.         if len(self.changed) > 0:
  1763.             pass
  1764.         self.btnPrinterPropertiesApply.set_sensitive(not (self.conflicts))
  1765.         self.btnPrinterPropertiesOK.set_sensitive(not (self.conflicts))
  1766.  
  1767.     
  1768.     def save_printer(self, printer, saveall = False, parent = None):
  1769.         if parent == None:
  1770.             parent = self.PrinterPropertiesDialog
  1771.         
  1772.         class_deleted = False
  1773.         name = printer.name
  1774.         if printer.is_class:
  1775.             self.cups._begin_operation(_('modifying class %s') % name)
  1776.         else:
  1777.             self.cups._begin_operation(_('modifying printer %s') % name)
  1778.         
  1779.         try:
  1780.             if not (printer.is_class) and self.ppd:
  1781.                 self.getPrinterSettings()
  1782.                 if self.ppd.nondefaultsMarked() or saveall:
  1783.                     self.cups.addPrinter(name, ppd = self.ppd)
  1784.                 
  1785.             
  1786.             if printer.is_class:
  1787.                 new_members = getCurrentClassMembers(self.tvClassMembers)
  1788.                 if not new_members:
  1789.                     dialog = gtk.MessageDialog(flags = 0, type = gtk.MESSAGE_WARNING, buttons = gtk.BUTTONS_YES_NO, message_format = _('This will delete this class!'))
  1790.                     dialog.format_secondary_text(_('Proceed anyway?'))
  1791.                     result = dialog.run()
  1792.                     dialog.destroy()
  1793.                     if result == gtk.RESPONSE_NO:
  1794.                         self.cups._end_operation()
  1795.                         return True
  1796.                     class_deleted = True
  1797.                 
  1798.                 old_members = printer.class_members[:]
  1799.                 for member in new_members:
  1800.                     if member in old_members:
  1801.                         old_members.remove(member)
  1802.                         continue
  1803.                     self.cups.addPrinterToClass(member, name)
  1804.                 
  1805.                 for member in old_members:
  1806.                     self.cups.deletePrinterFromClass(member, name)
  1807.                 
  1808.             
  1809.             location = self.entPLocation.get_text()
  1810.             info = self.entPDescription.get_text()
  1811.             device_uri = self.entPDevice.get_text()
  1812.             enabled = self.chkPEnabled.get_active()
  1813.             accepting = self.chkPAccepting.get_active()
  1814.             shared = self.chkPShared.get_active()
  1815.             if info != printer.info or saveall:
  1816.                 self.cups.setPrinterInfo(name, info)
  1817.             
  1818.             if location != printer.location or saveall:
  1819.                 self.cups.setPrinterLocation(name, location)
  1820.             
  1821.             if not (printer.is_class):
  1822.                 if device_uri != printer.device_uri or saveall:
  1823.                     self.cups.setPrinterDevice(name, device_uri)
  1824.                 
  1825.             if enabled != printer.enabled or saveall:
  1826.                 self.printer.setEnabled(enabled)
  1827.             
  1828.             if accepting == printer.rejecting or saveall:
  1829.                 self.printer.setAccepting(accepting)
  1830.             
  1831.             if shared != printer.is_shared or saveall:
  1832.                 self.printer.setShared(shared)
  1833.             
  1834.             
  1835.             def get_combo_value(cmb):
  1836.                 model = cmb.get_model()
  1837.                 iter = cmb.get_active_iter()
  1838.                 return model.get_value(iter, 1)
  1839.  
  1840.             job_sheet_start = get_combo_value(self.cmbPStartBanner)
  1841.             job_sheet_end = get_combo_value(self.cmbPEndBanner)
  1842.             error_policy = get_combo_value(self.cmbPErrorPolicy)
  1843.             op_policy = get_combo_value(self.cmbPOperationPolicy)
  1844.             if job_sheet_start != printer.job_sheet_start or job_sheet_end != printer.job_sheet_end or saveall:
  1845.                 printer.setJobSheets(job_sheet_start, job_sheet_end)
  1846.             
  1847.             if error_policy != printer.error_policy or saveall:
  1848.                 printer.setErrorPolicy(error_policy)
  1849.             
  1850.             if op_policy != printer.op_policy or saveall:
  1851.                 printer.setOperationPolicy(op_policy)
  1852.             
  1853.             default_allow = self.rbtnPAllow.get_active()
  1854.             except_users = self.getPUsers()
  1855.             if default_allow != printer.default_allow or except_users != printer.except_users or saveall:
  1856.                 printer.setAccess(default_allow, except_users)
  1857.             
  1858.             for option in printer.attributes:
  1859.                 if option not in self.server_side_options:
  1860.                     printer.unsetOption(option)
  1861.                     continue
  1862.             
  1863.             for option in self.server_side_options.itervalues():
  1864.                 if (option.is_changed() or saveall) and option.get_current_value() != option.system_default:
  1865.                     printer.setOption(option.name, option.get_current_value())
  1866.                     continue
  1867.         except cups.IPPError:
  1868.             (e, s) = None
  1869.             show_IPP_Error(e, s, parent)
  1870.             self.cups._end_operation()
  1871.             return True
  1872.  
  1873.         self.cups._end_operation()
  1874.         self.changed = set()
  1875.         if not (self.cups._use_pk) and not self.__dict__.has_key('server_settings'):
  1876.             self.cups._begin_operation(_('fetching server settings'))
  1877.             
  1878.             try:
  1879.                 self.server_settings = self.cups.adminGetServerSettings()
  1880.             except:
  1881.                 nonfatalException()
  1882.  
  1883.             self.cups._end_operation()
  1884.         
  1885.         if class_deleted:
  1886.             self.monitor.update()
  1887.         else:
  1888.             self.cups._begin_operation(_('obtaining queue details'))
  1889.             
  1890.             try:
  1891.                 printers = cupshelpers.getPrinters(self.cups)
  1892.                 this_printer = {
  1893.                     name: printers[name] }
  1894.                 self.printers.update(this_printer)
  1895.             except cups.IPPError:
  1896.                 (e, s) = None
  1897.                 show_IPP_Error(e, s, self.PrinterPropertiesDialog)
  1898.             except KeyError:
  1899.                 self.populateList()
  1900.  
  1901.             self.cups._end_operation()
  1902.         return False
  1903.  
  1904.     
  1905.     def getPrinterSettings(self):
  1906.         for option in self.options.itervalues():
  1907.             option.writeback()
  1908.         
  1909.  
  1910.     
  1911.     def on_tvPrinterProperties_selection_changed(self, selection):
  1912.         (model, iter) = selection.get_selected()
  1913.         if iter:
  1914.             self.printer_properties_last_iter_selected = iter
  1915.         else:
  1916.             
  1917.             try:
  1918.                 iter = self.printer_properties_last_iter_selected
  1919.             except AttributeError:
  1920.                 return None
  1921.  
  1922.             if model.iter_is_valid(iter):
  1923.                 selection.select_iter(iter)
  1924.             
  1925.  
  1926.     
  1927.     def on_tvPrinterProperties_cursor_changed(self, treeview):
  1928.         (path, column) = treeview.get_cursor()
  1929.         if path != None:
  1930.             model = treeview.get_model()
  1931.             iter = model.get_iter(path)
  1932.             n = model.get_value(iter, 1)
  1933.             self.ntbkPrinter.set_current_page(n)
  1934.         
  1935.  
  1936.     
  1937.     def set_system_or_user_default_printer(self, name):
  1938.         userdef = userdefault.UserDefaultPrinter()
  1939.         if name == self.default_printer:
  1940.             userdef.clear()
  1941.             self.populateList()
  1942.             return None
  1943.         userdefault.UserDefaultPrompt(self.set_default_printer, self.populateList, name, _('Set Default Printer'), self.PrintersWindow, _('Do you want to set this as the system-wide default printer?'), _('Set as the _system-wide default printer'), _('_Clear my personal default setting'), _('Set as my _personal default printer'))
  1944.  
  1945.     
  1946.     def set_default_printer(self, name):
  1947.         printer = self.printers[name]
  1948.         reload = False
  1949.         self.cups._begin_operation(_('setting default printer'))
  1950.         
  1951.         try:
  1952.             reload = printer.setAsDefault()
  1953.         except cups.HTTPError:
  1954.             (s,) = None
  1955.             show_HTTP_Error(s, self.PrintersWindow)
  1956.             self.cups._end_operation()
  1957.             return None
  1958.             except cups.IPPError:
  1959.                 (e, msg) = None
  1960.                 show_IPP_Error(e, msg, self.PrintersWindow)
  1961.                 self.cups._end_operation()
  1962.                 return None
  1963.             else:
  1964.                 self.cups._end_operation()
  1965.                 if reload:
  1966.                     self.reconnect()
  1967.                 
  1968.  
  1969.         
  1970.         try:
  1971.             self.populateList()
  1972.         except cups.HTTPError:
  1973.             (s,) = None
  1974.             self.cups = None
  1975.             self.setConnected()
  1976.             self.populateList()
  1977.             show_HTTP_Error(s, self.PrintersWindow)
  1978.  
  1979.  
  1980.     
  1981.     def on_btnPrintTestPage_clicked(self, button):
  1982.         if self.ppd == False:
  1983.             return None
  1984.         custom_testpage = None
  1985.         if self.ppd != False:
  1986.             opt = self.ppd.findOption('PageSize')
  1987.             if opt:
  1988.                 custom_testpage = os.path.join(pkgdata, 'testpage-%s.ps' % opt.defchoice.lower())
  1989.             
  1990.         
  1991.         user = cups.getUser()
  1992.         cups.setUser('')
  1993.         
  1994.         try:
  1995.             c = authconn.Connection(self.PrintersWindow, try_as_root = False, host = self.connect_server, encryption = self.connect_encrypt)
  1996.         except RuntimeError:
  1997.             s = None
  1998.             show_IPP_Error(None, s, self.PrintersWindow)
  1999.             return None
  2000.  
  2001.         job_id = None
  2002.         c._begin_operation(_('printing test page'))
  2003.         
  2004.         try:
  2005.             if custom_testpage and os.path.exists(custom_testpage):
  2006.                 debugprint('Printing custom test page ' + custom_testpage)
  2007.                 job_id = c.printTestPage(self.printer.name, file = custom_testpage)
  2008.             else:
  2009.                 debugprint('Printing default test page')
  2010.                 job_id = c.printTestPage(self.printer.name)
  2011.         except cups.IPPError:
  2012.             (e, msg) = None
  2013.             if e == cups.IPP_NOT_AUTHORIZED and self.connect_server != 'localhost' and self.connect_server[0] != '/':
  2014.                 show_error_dialog(_('Not possible'), _('The remote server did not accept the print job, most likely because the printer is not shared.'), self.PrintersWindow)
  2015.             else:
  2016.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2017.         except:
  2018.             self.connect_server[0] != '/'
  2019.  
  2020.         c._end_operation()
  2021.         cups.setUser(user)
  2022.         if job_id != None:
  2023.             show_info_dialog(_('Submitted'), _('Test page submitted as job %d') % job_id, parent = self.PrintersWindow)
  2024.         
  2025.  
  2026.     
  2027.     def maintenance_command(self, command):
  2028.         (tmpfd, tmpfname) = tempfile.mkstemp()
  2029.         os.write(tmpfd, '#CUPS-COMMAND\n%s\n' % command)
  2030.         os.close(tmpfd)
  2031.         self.cups._begin_operation(_('sending maintenance command'))
  2032.         
  2033.         try:
  2034.             format = 'application/vnd.cups-command'
  2035.             job_id = self.cups.printTestPage(self.printer.name, format = format, file = tmpfname, user = self.connect_user)
  2036.             show_info_dialog(_('Submitted'), _('Maintenance command submitted as job %d') % job_id, parent = self.PrintersWindow)
  2037.         except cups.IPPError:
  2038.             (e, msg) = None
  2039.             if e == cups.IPP_NOT_AUTHORIZED and self.printer.name != 'localhost':
  2040.                 show_error_dialog(_('Not possible'), _('The remote server did not accept the print job, most likely because the printer is not shared.'), self.PrintersWindow)
  2041.             else:
  2042.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2043.         except:
  2044.             self.printer.name != 'localhost'
  2045.  
  2046.         self.cups._end_operation()
  2047.         os.unlink(tmpfname)
  2048.  
  2049.     
  2050.     def on_btnSelfTest_clicked(self, button):
  2051.         self.maintenance_command('PrintSelfTestPage')
  2052.  
  2053.     
  2054.     def on_btnCleanHeads_clicked(self, button):
  2055.         self.maintenance_command('Clean all')
  2056.  
  2057.     
  2058.     def fillComboBox(self, combobox, values, value, translationdict = None):
  2059.         if translationdict == None:
  2060.             translationdict = ppdippstr.TranslactionDict()
  2061.         
  2062.         model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
  2063.         combobox.set_model(model)
  2064.         set_active = False
  2065.         for nr, val in enumerate(values):
  2066.             model.append([
  2067.                 translationdict.get(val),
  2068.                 val])
  2069.             if val == value:
  2070.                 combobox.set_active(nr)
  2071.                 set_active = True
  2072.                 continue
  2073.         
  2074.         if not set_active:
  2075.             combobox.set_active(0)
  2076.         
  2077.  
  2078.     
  2079.     def fillPrinterTab(self, name):
  2080.         self.changed = set()
  2081.         self.options = { }
  2082.         self.conflicts = set()
  2083.         printer = self.printers[name]
  2084.         self.printer = printer
  2085.         printer.getAttributes()
  2086.         
  2087.         try:
  2088.             publishing = printer.other_attributes['server-is-sharing-printers']
  2089.             self.server_is_publishing = publishing
  2090.         except KeyError:
  2091.             pass
  2092.  
  2093.         editable = not (self.printer.discovered)
  2094.         editablePPD = not (self.printer.remote)
  2095.         
  2096.         try:
  2097.             self.ppd = printer.getPPD()
  2098.             self.ppd_local = printer.getPPD()
  2099.             if self.ppd_local != False:
  2100.                 self.ppd_local.localize()
  2101.         except cups.IPPError:
  2102.             (e, m) = None
  2103.             show_IPP_Error(e, m, self.PrintersWindow)
  2104.             self.ppd = False
  2105.         except RuntimeError:
  2106.             show_error_dialog(_('Error'), _('There was a problem connecting to the CUPS server.'), self.PrintersWindow)
  2107.             raise 
  2108.  
  2109.         for widget in (self.entPDescription, self.entPLocation, self.entPDevice):
  2110.             widget.set_editable(editable)
  2111.         
  2112.         for widget in (self.btnSelectDevice, self.btnChangePPD, self.chkPEnabled, self.chkPAccepting, self.chkPShared, self.cmbPStartBanner, self.cmbPEndBanner, self.cmbPErrorPolicy, self.cmbPOperationPolicy, self.rbtnPAllow, self.rbtnPDeny, self.tvPUsers, self.entPUser, self.btnPAddUser, self.btnPDelUser):
  2113.             widget.set_sensitive(editable)
  2114.         
  2115.         self.entPDescription.set_text(printer.info)
  2116.         self.entPLocation.set_text(printer.location)
  2117.         uri = printer.device_uri
  2118.         self.entPDevice.set_text(uri)
  2119.         self.changed.discard(self.entPDevice)
  2120.         for widget in (self.lblPMakeModel2, self.lblPMakeModel, self.btnChangePPD, self.lblPDevice2, self.entPDevice, self.btnSelectDevice):
  2121.             if printer.is_class:
  2122.                 widget.hide()
  2123.                 continue
  2124.             widget.show()
  2125.         
  2126.         
  2127.         try:
  2128.             if printer.is_shared:
  2129.                 if self.server_is_publishing:
  2130.                     self.lblNotPublished.hide_all()
  2131.                 else:
  2132.                     self.lblNotPublished.show_all()
  2133.             else:
  2134.                 self.lblNotPublished.hide_all()
  2135.         except:
  2136.             nonfatalException()
  2137.             self.lblNotPublished.hide_all()
  2138.  
  2139.         self.cmbPStartBanner.set_sensitive(editable)
  2140.         self.cmbPEndBanner.set_sensitive(editable)
  2141.         self.cmbPErrorPolicy.set_sensitive(editable)
  2142.         self.cmbPOperationPolicy.set_sensitive(editable)
  2143.         self.entPUser.set_text('')
  2144.         self.server_side_options = { }
  2145.         for option in self.job_options_widgets.values():
  2146.             if option.name == 'media' and self.ppd:
  2147.                 opt = self.ppd.findOption('PageSize')
  2148.                 if opt:
  2149.                     option.set_default(opt.defchoice)
  2150.                 
  2151.             
  2152.             option_editable = editable
  2153.             
  2154.             try:
  2155.                 value = self.printer.attributes[option.name]
  2156.             except KeyError:
  2157.                 option.reinit(None)
  2158.  
  2159.             
  2160.             try:
  2161.                 if self.printer.possible_attributes.has_key(option.name):
  2162.                     supported = self.printer.possible_attributes[option.name][1]
  2163.                     option.reinit(value, supported = supported)
  2164.                 else:
  2165.                     option.reinit(value)
  2166.                 self.server_side_options[option.name] = option
  2167.             except:
  2168.                 option_editable = False
  2169.                 show_error_dialog(_('Error'), _("Option '%s' has value '%s' and cannot be edited.") % (option.name, value), self.PrintersWindow)
  2170.  
  2171.             option.widget.set_sensitive(option_editable)
  2172.             if not editable:
  2173.                 option.button.set_sensitive(False)
  2174.                 continue
  2175.         
  2176.         self.other_job_options = []
  2177.         self.draw_other_job_options(editable = editable)
  2178.         for option in self.printer.attributes.keys():
  2179.             if self.server_side_options.has_key(option):
  2180.                 continue
  2181.             
  2182.             value = self.printer.attributes[option]
  2183.             if self.printer.possible_attributes.has_key(option):
  2184.                 supported = self.printer.possible_attributes[option][1]
  2185.             elif isinstance(value, bool):
  2186.                 supported = [
  2187.                     'true',
  2188.                     'false']
  2189.                 value = str(value).lower()
  2190.             else:
  2191.                 supported = ''
  2192.                 value = str(value)
  2193.             self.add_job_option(option, value = value, supported = supported, is_new = False, editable = editable)
  2194.         
  2195.         self.entNewJobOption.set_text('')
  2196.         self.entNewJobOption.set_sensitive(editable)
  2197.         self.btnNewJobOption.set_sensitive(False)
  2198.         if printer.is_class:
  2199.             tab_nr = self.ntbkPrinter.page_num(self.swPInstallOptions)
  2200.             if tab_nr != -1:
  2201.                 self.ntbkPrinter.remove_page(tab_nr)
  2202.             
  2203.             self.fillClassMembers(name, editable)
  2204.         else:
  2205.             self.fillPrinterOptions(name, editablePPD)
  2206.         self.updateMarkerLevels()
  2207.         self.updateStateReasons()
  2208.         self.updatePrinterPropertiesTreeView()
  2209.         self.changed = set()
  2210.         self.updatePrinterProperties()
  2211.         self.setDataButtonState()
  2212.  
  2213.     
  2214.     def updatePrinterPropertiesTreeView(self):
  2215.         store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT)
  2216.         self.ntbkPrinter.set_show_tabs(False)
  2217.         for n in range(self.ntbkPrinter.get_n_pages()):
  2218.             page = self.ntbkPrinter.get_nth_page(n)
  2219.             label = self.ntbkPrinter.get_tab_label(page)
  2220.             iter = store.append(None)
  2221.             store.set_value(iter, 0, label.get_text())
  2222.             store.set_value(iter, 1, n)
  2223.         
  2224.         sel = self.tvPrinterProperties.get_selection()
  2225.         self.tvPrinterProperties.set_model(store)
  2226.  
  2227.     
  2228.     def updateMarkerLevels(self):
  2229.         printer = self.printer
  2230.         for widget in self.vboxMarkerLevels.get_children():
  2231.             self.vboxMarkerLevels.remove(widget)
  2232.         
  2233.         marker_info = dict()
  2234.         for attr in [
  2235.             'marker-colors',
  2236.             'marker-names',
  2237.             'marker-types',
  2238.             'marker-levels']:
  2239.             marker_info[attr] = printer.other_attributes.get(attr, [])
  2240.         
  2241.         markers = map((lambda color, name, type, level: (color, name, type, level)), marker_info['marker-colors'], marker_info['marker-names'], marker_info['marker-types'], marker_info['marker-levels'])
  2242.         debugprint(markers)
  2243.         can_refresh = self.printer.type & cups.CUPS_PRINTER_COMMANDS != 0
  2244.         self.btnRefreshMarkerLevels.set_sensitive(can_refresh)
  2245.         if len(markers) == 0:
  2246.             label = gtk.Label(_('Marker levels are not reported for this printer.'))
  2247.             label.set_line_wrap(True)
  2248.             label.set_alignment(0, 0)
  2249.             self.vboxMarkerLevels.pack_start(label, False, False, 0)
  2250.         else:
  2251.             num_markers = 0
  2252.             cols = len(markers)
  2253.             rows = 1 + (cols - 1) / 4
  2254.             if cols > 4:
  2255.                 cols = 4
  2256.             
  2257.             table = gtk.Table(rows = rows, columns = cols, homogeneous = True)
  2258.             table.set_col_spacings(6)
  2259.             table.set_row_spacings(12)
  2260.             self.vboxMarkerLevels.pack_start(table)
  2261.             for color, name, marker_type, level in markers:
  2262.                 if name == None:
  2263.                     name = ''
  2264.                 
  2265.                 row = num_markers / 4
  2266.                 col = num_markers % 4
  2267.                 vbox = gtk.VBox(spacing = 6)
  2268.                 subhbox = gtk.HBox()
  2269.                 inklevel = gtkinklevel.GtkInkLevel(color, level)
  2270.                 subhbox.pack_start(inklevel, True, False, 0)
  2271.                 vbox.pack_start(subhbox, False, False, 0)
  2272.                 label = gtk.Label(name)
  2273.                 label.set_line_wrap(True)
  2274.                 vbox.pack_start(label, False, False, 0)
  2275.                 table.attach(vbox, col, col + 1, row, row + 1)
  2276.                 num_markers += 1
  2277.             
  2278.         self.vboxMarkerLevels.show_all()
  2279.  
  2280.     
  2281.     def on_btnRefreshMarkerLevels_clicked(self, button):
  2282.         self.maintenance_command('ReportLevels')
  2283.  
  2284.     
  2285.     def updateStateReasons(self):
  2286.         printer = self.printer
  2287.         reasons = printer.other_attributes.get('printer-state-reasons', [])
  2288.         store = gtk.ListStore(int, str)
  2289.         any = False
  2290.         for reason in reasons:
  2291.             if reason == 'none':
  2292.                 break
  2293.             
  2294.             any = True
  2295.             iter = store.append(None)
  2296.             r = statereason.StateReason(printer.name, reason)
  2297.             store.set_value(iter, 0, r.get_level())
  2298.             (title, text) = r.get_description()
  2299.             store.set_value(iter, 1, text)
  2300.         
  2301.         self.tvPrinterStateReasons.set_model(store)
  2302.         page = 0
  2303.         if any:
  2304.             page = 1
  2305.         
  2306.         self.ntbkPrinterStateReasons.set_current_page(page)
  2307.  
  2308.     
  2309.     def set_printer_state_reason_icon(self, column, cell, model, iter, *data):
  2310.         level = model.get_value(iter, 0)
  2311.         icon = statereason.StateReason.LEVEL_ICON[level]
  2312.         theme = gtk.icon_theme_get_default()
  2313.         
  2314.         try:
  2315.             pixbuf = theme.load_icon(icon, 22, 0)
  2316.             cell.set_property('pixbuf', pixbuf)
  2317.         except gobject.GError:
  2318.             exc = None
  2319.  
  2320.  
  2321.     
  2322.     def set_printer_state_reason_text(self, column, cell, model, iter, *data):
  2323.         cell.set_property('text', model.get_value(iter, 1))
  2324.  
  2325.     
  2326.     def updatePrinterProperties(self):
  2327.         debugprint('update printer properties')
  2328.         printer = self.printer
  2329.         self.lblPMakeModel.set_text(printer.make_and_model)
  2330.         state = self.printer_states.get(printer.state, _('Unknown'))
  2331.         reason = printer.other_attributes.get('printer-state-message', '')
  2332.         if len(reason) > 0:
  2333.             state += ' - ' + reason
  2334.         
  2335.         self.lblPState.set_text(state)
  2336.         if len(self.changed) == 0:
  2337.             debugprint('no changes yet: full printer properties update')
  2338.             self.chkPEnabled.set_active(printer.enabled)
  2339.             self.chkPAccepting.set_active(not (printer.rejecting))
  2340.             self.chkPShared.set_active(printer.is_shared)
  2341.             (self.fillComboBox(self.cmbPStartBanner, printer.job_sheets_supported, printer.job_sheet_start, ppdippstr.job_sheets),)
  2342.             self.fillComboBox(self.cmbPEndBanner, printer.job_sheets_supported, printer.job_sheet_end, ppdippstr.job_sheets)
  2343.             self.fillComboBox(self.cmbPErrorPolicy, printer.error_policy_supported, printer.error_policy, ppdippstr.printer_error_policy)
  2344.             self.fillComboBox(self.cmbPOperationPolicy, printer.op_policy_supported, printer.op_policy, ppdippstr.printer_op_policy)
  2345.             self.rbtnPAllow.set_active(printer.default_allow)
  2346.             self.rbtnPDeny.set_active(not (printer.default_allow))
  2347.             self.setPUsers(printer.except_users)
  2348.             self.updateMarkerLevels()
  2349.             self.updateStateReasons()
  2350.             self.updatePrinterPropertiesTreeView
  2351.         
  2352.  
  2353.     
  2354.     def fillPrinterOptions(self, name, editable):
  2355.         tab_nr = self.ntbkPrinter.page_num(self.algnClassMembers)
  2356.         if tab_nr != -1:
  2357.             self.ntbkPrinter.remove_page(tab_nr)
  2358.         
  2359.         for widget in self.vbPInstallOptions.get_children():
  2360.             self.vbPInstallOptions.remove(widget)
  2361.         
  2362.         for widget in self.vbPOptions.get_children():
  2363.             self.vbPOptions.remove(widget)
  2364.         
  2365.         if self.ntbkPrinter.page_num(self.swPOptions) == -1:
  2366.             self.ntbkPrinter.insert_page(self.swPOptions, self.lblPOptions, self.static_tabs)
  2367.         
  2368.         if not self.ppd:
  2369.             tab_nr = self.ntbkPrinter.page_num(self.swPInstallOptions)
  2370.             if tab_nr != -1:
  2371.                 self.ntbkPrinter.remove_page(tab_nr)
  2372.             
  2373.             tab_nr = self.ntbkPrinter.page_num(self.swPOptions)
  2374.             if tab_nr != -1:
  2375.                 self.ntbkPrinter.remove_page(tab_nr)
  2376.             
  2377.             return None
  2378.         ppd = self.ppd
  2379.         ppd.markDefaults()
  2380.         self.ppd_local.markDefaults()
  2381.         hasInstallableOptions = False
  2382.         for group in self.ppd_local.optionGroups:
  2383.             table = gtk.Table(1, 3, False)
  2384.             table.set_col_spacings(6)
  2385.             table.set_row_spacings(6)
  2386.             container.add(table)
  2387.             rows = 0
  2388.             self.option_inputslot = None
  2389.             self.option_manualfeed = None
  2390.             for nr, option in enumerate(group.options):
  2391.                 if option.keyword == 'PageRegion':
  2392.                     continue
  2393.                 
  2394.                 rows += 1
  2395.                 table.resize(rows, 3)
  2396.                 o = OptionWidget(option, ppd, self, tab_label = tab_label)
  2397.                 table.attach(o.conflictIcon, 0, 1, nr, nr + 1, 0, 0, 0, 0)
  2398.                 hbox = gtk.HBox()
  2399.                 if o.label:
  2400.                     a = gtk.Alignment(0.5, 0.5, 1, 1)
  2401.                     a.set_padding(0, 0, 0, 6)
  2402.                     a.add(o.label)
  2403.                     table.attach(a, 1, 2, nr, nr + 1, gtk.FILL, 0, 0, 0)
  2404.                     table.attach(hbox, 2, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  2405.                 else:
  2406.                     table.attach(hbox, 1, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  2407.                 hbox.pack_start(o.selector, False)
  2408.                 self.options[option.keyword] = o
  2409.                 o.selector.set_sensitive(editable)
  2410.                 if option.keyword == 'InputSlot':
  2411.                     self.option_inputslot = o
  2412.                     continue
  2413.                 if option.keyword == 'ManualFeed':
  2414.                     self.option_manualfeed = o
  2415.                     continue
  2416.             
  2417.         
  2418.         if not hasInstallableOptions:
  2419.             tab_nr = self.ntbkPrinter.page_num(self.swPInstallOptions)
  2420.             if tab_nr != -1:
  2421.                 self.ntbkPrinter.remove_page(tab_nr)
  2422.             
  2423.         
  2424.         for option in self.options.itervalues():
  2425.             conflicts = option.checkConflicts()
  2426.             if conflicts:
  2427.                 self.conflicts.add(option)
  2428.                 continue
  2429.         
  2430.         self.swPInstallOptions.show_all()
  2431.         self.swPOptions.show_all()
  2432.  
  2433.     
  2434.     def fillClassMembers(self, name, editable):
  2435.         printer = self.printers[name]
  2436.         self.btnClassAddMember.set_sensitive(editable)
  2437.         self.btnClassDelMember.set_sensitive(editable)
  2438.         tab_nr = self.ntbkPrinter.page_num(self.swPOptions)
  2439.         if tab_nr != -1:
  2440.             self.ntbkPrinter.remove_page(tab_nr)
  2441.         
  2442.         if self.ntbkPrinter.page_num(self.algnClassMembers) == -1:
  2443.             self.ntbkPrinter.insert_page(self.algnClassMembers, self.lblClassMembers, self.static_tabs)
  2444.         
  2445.         model_members = self.tvClassMembers.get_model()
  2446.         model_not_members = self.tvClassNotMembers.get_model()
  2447.         model_members.clear()
  2448.         model_not_members.clear()
  2449.         names = self.printers.keys()
  2450.         names.sort()
  2451.         for name in names:
  2452.             p = self.printers[name]
  2453.             if p is not printer:
  2454.                 if name in printer.class_members:
  2455.                     model_members.append((name,))
  2456.                 else:
  2457.                     model_not_members.append((name,))
  2458.             name in printer.class_members
  2459.         
  2460.  
  2461.     
  2462.     def on_btnClassAddMember_clicked(self, button):
  2463.         moveClassMembers(self.tvClassNotMembers, self.tvClassMembers)
  2464.         if getCurrentClassMembers(self.tvClassMembers) != self.printer.class_members:
  2465.             self.changed.add(self.tvClassMembers)
  2466.         else:
  2467.             self.changed.discard(self.tvClassMembers)
  2468.         self.setDataButtonState()
  2469.  
  2470.     
  2471.     def on_btnClassDelMember_clicked(self, button):
  2472.         moveClassMembers(self.tvClassMembers, self.tvClassNotMembers)
  2473.         if getCurrentClassMembers(self.tvClassMembers) != self.printer.class_members:
  2474.             self.changed.add(self.tvClassMembers)
  2475.         else:
  2476.             self.changed.discard(self.tvClassMembers)
  2477.         self.setDataButtonState()
  2478.  
  2479.     
  2480.     def on_quit_activate(self, widget, event = None):
  2481.         self.monitor.cleanup()
  2482.         while len(self.jobviewers) > 0:
  2483.             self.jobviewers[0].cleanup()
  2484.         gtk.main_quit()
  2485.  
  2486.     
  2487.     def is_rename_possible(self, name):
  2488.         jobs = self.printers[name].jobsQueued()
  2489.         if len(jobs) > 0:
  2490.             show_error_dialog(_('Cannot Rename'), _('There are queued jobs.'), parent = self.PrintersWindow)
  2491.             return False
  2492.         return True
  2493.  
  2494.     
  2495.     def on_rename_activate(self, UNUSED):
  2496.         tuple = self.dests_iconview.get_cursor()
  2497.         if tuple == None:
  2498.             return None
  2499.         (path, cell) = tuple
  2500.         if type(cell) != gtk.CellRendererText:
  2501.             cells = self.dests_iconview.get_cells()
  2502.             for cell in cells:
  2503.                 if type(cell) == gtk.CellRendererText:
  2504.                     break
  2505.                     continue
  2506.                 tuple == None
  2507.             
  2508.             if type(cell) != gtk.CellRendererText:
  2509.                 return None
  2510.         
  2511.         model = self.dests_iconview.get_model()
  2512.         iter = model.get_iter(path)
  2513.         name = unicode(model.get_value(iter, 2))
  2514.         if not self.is_rename_possible(name):
  2515.             return None
  2516.         cell.set_property('editable', True)
  2517.         self.dests_iconview.set_cursor(path, cell, start_editing = True)
  2518.         ids = []
  2519.         ids.append(cell.connect('edited', self.printer_name_edited))
  2520.         ids.append(cell.connect('editing-canceled', self.printer_name_edit_cancel))
  2521.         self.rename_sigids = ids
  2522.  
  2523.     
  2524.     def printer_name_edited(self, cell, path, newname):
  2525.         model = self.dests_iconview.get_model()
  2526.         iter = model.get_iter(path)
  2527.         name = unicode(model.get_value(iter, 2))
  2528.         debugprint('edited: %s -> %s' % (name, newname))
  2529.         
  2530.         try:
  2531.             self.rename_printer(name, newname)
  2532.         finally:
  2533.             cell.stop_editing(canceled = False)
  2534.             cell.set_property('editable', False)
  2535.             for id in self.rename_sigids:
  2536.                 cell.disconnect(id)
  2537.             
  2538.  
  2539.  
  2540.     
  2541.     def printer_name_edit_cancel(self, cell):
  2542.         debugprint('editing-canceled')
  2543.         cell.stop_editing(canceled = True)
  2544.         cell.set_property('editable', False)
  2545.         for id in self.rename_sigids:
  2546.             cell.disconnect(id)
  2547.         
  2548.  
  2549.     
  2550.     def rename_printer(self, old_name, new_name):
  2551.         if old_name == new_name:
  2552.             return None
  2553.         
  2554.         try:
  2555.             self.fillPrinterTab(old_name)
  2556.         except RuntimeError:
  2557.             old_name == new_name
  2558.             old_name == new_name
  2559.         except:
  2560.             old_name == new_name
  2561.  
  2562.         if not self.is_rename_possible(old_name):
  2563.             return None
  2564.         self.cups._begin_operation(_('renaming printer'))
  2565.         rejecting = self.printer.rejecting
  2566.         if not rejecting:
  2567.             
  2568.             try:
  2569.                 self.printer.setAccepting(False)
  2570.                 if not self.is_rename_possible(old_name):
  2571.                     self.printer.setAccepting(True)
  2572.                     self.cups._end_operation()
  2573.                     return None
  2574.             except cups.IPPError:
  2575.                 self.is_rename_possible(old_name)
  2576.                 (e, msg) = self.is_rename_possible(old_name)
  2577.                 old_name == new_name
  2578.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2579.                 self.cups._end_operation()
  2580.                 return None
  2581.             
  2582.  
  2583.         self.is_rename_possible(old_name)<EXCEPTION MATCH>cups.IPPError
  2584.         if self.copy_printer(new_name):
  2585.             self.monitor.update()
  2586.             if not rejecting:
  2587.                 
  2588.                 try:
  2589.                     self.printers[old_name].setAccepting(True)
  2590.                 except cups.HTTPError:
  2591.                     self.is_rename_possible(old_name)
  2592.                     (s,) = self.is_rename_possible(old_name)
  2593.                     self.is_rename_possible(old_name)
  2594.                     show_HTTP_Error(s, self.PrintersWindow)
  2595.                 except cups.IPPError:
  2596.                     self.is_rename_possible(old_name)
  2597.                     (e, msg) = self.is_rename_possible(old_name)
  2598.                     self.is_rename_possible(old_name)
  2599.                     show_IPP_Error(e, msg, self.PrintersWindow)
  2600.                 except:
  2601.                     self.is_rename_possible(old_name)<EXCEPTION MATCH>cups.HTTPError
  2602.                 
  2603.  
  2604.             self.is_rename_possible(old_name)
  2605.             self.cups._end_operation()
  2606.             return None
  2607.         if not rejecting:
  2608.             
  2609.             try:
  2610.                 self.printer.setAccepting(True)
  2611.             except cups.HTTPError:
  2612.                 self.copy_printer(new_name)
  2613.                 (s,) = self.copy_printer(new_name)
  2614.                 self.is_rename_possible(old_name)
  2615.                 show_HTTP_Error(s, self.PrintersWindow)
  2616.             except cups.IPPError:
  2617.                 self.copy_printer(new_name)
  2618.                 (e, msg) = self.copy_printer(new_name)
  2619.                 self.copy_printer(new_name)
  2620.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2621.             except:
  2622.                 self.copy_printer(new_name)<EXCEPTION MATCH>cups.HTTPError
  2623.             
  2624.  
  2625.         self.copy_printer(new_name)
  2626.         
  2627.         try:
  2628.             self.cups.deletePrinter(old_name)
  2629.         except cups.HTTPError:
  2630.             None if self.default_printer == old_name else old_name == new_name
  2631.             (s,) = None if self.default_printer == old_name else old_name == new_name
  2632.             show_HTTP_Error(s, self.PrintersWindow)
  2633.         except cups.IPPError:
  2634.             (e, msg) = None
  2635.             show_IPP_Error(e, msg, self.PrintersWindow)
  2636.         except:
  2637.             None if self.default_printer == old_name else old_name == new_name
  2638.  
  2639.         self.cups._end_operation()
  2640.         
  2641.         def select_new_printer(model, path, iter):
  2642.             name = unicode(model.get_value(iter, 2))
  2643.             print name, new_name
  2644.             if name == new_name:
  2645.                 self.dests_iconview.select_path(path)
  2646.             
  2647.  
  2648.         self.populateList()
  2649.         model = self.dests_iconview.get_model()
  2650.         model.foreach(select_new_printer)
  2651.  
  2652.     
  2653.     def copy_printer(self, new_name):
  2654.         self.printer.name = new_name
  2655.         self.printer.class_members = []
  2656.         self.cups._begin_operation(_('copying printer'))
  2657.         ret = self.save_printer(self.printer, saveall = True, parent = self.PrintersWindow)
  2658.         self.cups._end_operation()
  2659.         return ret
  2660.  
  2661.     
  2662.     def on_copy_activate(self, UNUSED):
  2663.         iconview = self.dests_iconview
  2664.         paths = iconview.get_selected_items()
  2665.         model = self.dests_iconview.get_model()
  2666.         iter = model.get_iter(paths[0])
  2667.         name = unicode(model.get_value(iter, 2))
  2668.         self.entCopyName.set_text(name)
  2669.         self.NewPrinterName.set_transient_for(self.PrintersWindow)
  2670.         result = self.NewPrinterName.run()
  2671.         self.NewPrinterName.hide()
  2672.         if result == gtk.RESPONSE_CANCEL:
  2673.             return None
  2674.         
  2675.         try:
  2676.             self.fillPrinterTab(name)
  2677.         except RuntimeError:
  2678.             result == gtk.RESPONSE_CANCEL
  2679.             result == gtk.RESPONSE_CANCEL
  2680.         except:
  2681.             result == gtk.RESPONSE_CANCEL
  2682.  
  2683.         self.copy_printer(self.entCopyName.get_text())
  2684.         self.monitor.update()
  2685.  
  2686.     
  2687.     def on_entCopyName_changed(self, widget):
  2688.         text = unicode(widget.get_text())
  2689.         new_text = text
  2690.         new_text = new_text.replace('/', '')
  2691.         new_text = new_text.replace('#', '')
  2692.         new_text = new_text.replace(' ', '')
  2693.         if text != new_text:
  2694.             widget.set_text(new_text)
  2695.         
  2696.         self.btnCopyOk.set_sensitive(self.checkNPName(new_text))
  2697.  
  2698.     
  2699.     def on_delete_activate(self, UNUSED):
  2700.         if isinstance(self.current_groups_pane_item, StaticGroupItem):
  2701.             paths = self.dests_iconview.get_selected_items()
  2702.             model = self.dests_iconview.get_model()
  2703.             selected_names = []
  2704.             for path in paths:
  2705.                 selected_names.append(model[path][2])
  2706.             
  2707.             self.current_groups_pane_item.remove_queues(selected_names)
  2708.             self.populateList()
  2709.         else:
  2710.             self.delete_selected_printer_queues()
  2711.  
  2712.     
  2713.     def delete_selected_printer_queues(self):
  2714.         paths = self.dests_iconview.get_selected_items()
  2715.         model = self.dests_iconview.get_model()
  2716.         n = len(paths)
  2717.         if n == 1:
  2718.             iter = model.get_iter(paths[0])
  2719.             object = model.get_value(iter, 0)
  2720.             name = model.get_value(iter, 2)
  2721.             if object.is_class:
  2722.                 message_format = _("Really delete class '%s'?") % name
  2723.             else:
  2724.                 message_format = _("Really delete printer '%s'?") % name
  2725.         else:
  2726.             message_format = _('Really delete selected destinations?')
  2727.         dialog = gtk.MessageDialog(self.PrintersWindow, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, message_format)
  2728.         dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_DELETE, gtk.RESPONSE_ACCEPT)
  2729.         dialog.set_default_response(gtk.RESPONSE_REJECT)
  2730.         result = dialog.run()
  2731.         dialog.destroy()
  2732.         if result != gtk.RESPONSE_ACCEPT:
  2733.             return None
  2734.         
  2735.         try:
  2736.             for i in range(n):
  2737.                 iter = model.get_iter(paths[i])
  2738.                 name = model.get_value(iter, 2)
  2739.                 self.cups._begin_operation(_('deleting printer %s') % name)
  2740.                 name = unicode(name)
  2741.                 self.cups.deletePrinter(name)
  2742.                 self.cups._end_operation()
  2743.         except cups.IPPError:
  2744.             result != gtk.RESPONSE_ACCEPT
  2745.             (e, msg) = result != gtk.RESPONSE_ACCEPT
  2746.             self.cups._end_operation()
  2747.             show_IPP_Error(e, msg, self.PrintersWindow)
  2748.         except:
  2749.             result != gtk.RESPONSE_ACCEPT
  2750.  
  2751.         self.changed = set()
  2752.         self.monitor.update()
  2753.  
  2754.     
  2755.     def on_enabled_activate(self, toggle_action):
  2756.         if self.updating_widgets:
  2757.             return None
  2758.         enable = toggle_action.get_active()
  2759.         iconview = self.dests_iconview
  2760.         paths = iconview.get_selected_items()
  2761.         model = iconview.get_model()
  2762.         for i in range(len(paths)):
  2763.             iter = model.get_iter(paths[i])
  2764.             printer = model.get_value(iter, 0)
  2765.             name = unicode(model.get_value(iter, 2), 'utf-8')
  2766.             self.cups._begin_operation(_('modifying printer %s') % name)
  2767.             
  2768.             try:
  2769.                 printer.setEnabled(enable)
  2770.             except cups.IPPError:
  2771.                 self.updating_widgets
  2772.                 (e, m) = self.updating_widgets
  2773.                 errordialogs.show_IPP_Error(e, m, self.PrintersWindow)
  2774.                 self.cups._end_operation()
  2775.                 break
  2776.             except:
  2777.                 self.updating_widgets
  2778.  
  2779.             self.cups._end_operation()
  2780.         
  2781.         self.monitor.update()
  2782.  
  2783.     
  2784.     def on_shared_activate(self, menuitem):
  2785.         if self.updating_widgets:
  2786.             return None
  2787.         share = menuitem.get_active()
  2788.         iconview = self.dests_iconview
  2789.         paths = iconview.get_selected_items()
  2790.         model = iconview.get_model()
  2791.         success = False
  2792.         for i in range(len(paths)):
  2793.             iter = model.get_iter(paths[i])
  2794.             printer = model.get_value(iter, 0)
  2795.             self.cups._begin_operation(_('modifying printer %s') % printer.name)
  2796.             
  2797.             try:
  2798.                 printer.setShared(share)
  2799.                 success = True
  2800.             except cups.IPPError:
  2801.                 self.updating_widgets
  2802.                 (e, m) = self.updating_widgets
  2803.                 show_IPP_Error(e, m, self.PrintersWindow)
  2804.                 self.cups._end_operation()
  2805.                 break
  2806.             except:
  2807.                 self.updating_widgets
  2808.  
  2809.             self.cups._end_operation()
  2810.         
  2811.         if success and share:
  2812.             self.advise_publish()
  2813.         
  2814.         
  2815.         def deferred_refresh():
  2816.             self.populateList()
  2817.             return False
  2818.  
  2819.         gobject.idle_add(deferred_refresh)
  2820.  
  2821.     
  2822.     def advise_publish(self):
  2823.         if not self.server_is_publishing:
  2824.             show_info_dialog(_('Publish Shared Printers'), _("Shared printers are not available to other people unless the 'Publish shared printers' option is enabled in the server settings."), parent = self.PrintersWindow)
  2825.         
  2826.  
  2827.     
  2828.     def on_set_as_default_activate(self, UNUSED):
  2829.         iconview = self.dests_iconview
  2830.         paths = iconview.get_selected_items()
  2831.         model = iconview.get_model()
  2832.         iter = model.get_iter(paths[0])
  2833.         name = unicode(model.get_value(iter, 2))
  2834.         self.set_system_or_user_default_printer(name)
  2835.  
  2836.     
  2837.     def on_edit_activate(self, UNUSED):
  2838.         paths = self.dests_iconview.get_selected_items()
  2839.         self.dests_iconview_item_activated(self.dests_iconview, paths[0])
  2840.  
  2841.     
  2842.     def on_create_class_activate(self, UNUSED):
  2843.         paths = self.dests_iconview.get_selected_items()
  2844.         class_members = []
  2845.         model = self.dests_iconview.get_model()
  2846.         for path in paths:
  2847.             iter = model.get_iter(path)
  2848.             name = unicode(model.get_value(iter, 2), 'utf-8')
  2849.             class_members.append(name)
  2850.         
  2851.         self.newPrinterGUI.init('class')
  2852.         out_model = self.newPrinterGUI.tvNCNotMembers.get_model()
  2853.         in_model = self.newPrinterGUI.tvNCMembers.get_model()
  2854.         iter = out_model.get_iter_first()
  2855.         while iter != None:
  2856.             next = out_model.iter_next(iter)
  2857.             data = out_model.get(iter, 0)
  2858.             if data[0] in class_members:
  2859.                 in_model.append(data)
  2860.                 out_model.remove(iter)
  2861.             
  2862.             iter = next
  2863.  
  2864.     
  2865.     def on_view_print_queue_activate(self, UNUSED):
  2866.         paths = self.dests_iconview.get_selected_items()
  2867.         if len(paths):
  2868.             specific_dests = []
  2869.             model = self.dests_iconview.get_model()
  2870.             for path in paths:
  2871.                 iter = model.get_iter(path)
  2872.                 name = unicode(model.get_value(iter, 2), 'utf-8')
  2873.                 specific_dests.append(name)
  2874.             
  2875.             viewer = jobviewer.JobViewer(None, None, my_jobs = False, specific_dests = specific_dests, exit_handler = self.on_jobviewer_exit, parent = self.PrintersWindow)
  2876.         else:
  2877.             viewer = jobviewer.JobViewer(None, None, my_jobs = False, exit_handler = self.on_jobviewer_exit, parent = self.PrintersWindow)
  2878.         self.jobviewers.append(viewer)
  2879.  
  2880.     
  2881.     def on_jobviewer_exit(self, viewer):
  2882.         i = self.jobviewers.index(viewer)
  2883.         del self.jobviewers[i]
  2884.  
  2885.     
  2886.     def on_view_groups_activate(self, widget):
  2887.         if widget.get_active():
  2888.             if not self.groups_pane_visible:
  2889.                 self.view_area_vbox.remove(self.view_area_scrolledwindow)
  2890.                 self.view_area_hpaned.add2(self.view_area_scrolledwindow)
  2891.                 self.view_area_vbox.add(self.view_area_hpaned)
  2892.                 self.view_area_vbox.show_all()
  2893.                 self.groups_pane_visible = True
  2894.             
  2895.         elif self.groups_pane_visible:
  2896.             self.view_area_vbox.remove(self.view_area_hpaned)
  2897.             self.view_area_hpaned.remove(self.view_area_scrolledwindow)
  2898.             self.view_area_vbox.add(self.view_area_scrolledwindow)
  2899.             self.view_area_vbox.show_all()
  2900.             self.groups_pane_visible = False
  2901.         
  2902.  
  2903.     
  2904.     def on_view_discovered_printers_activate(self, UNUSED):
  2905.         self.populateList()
  2906.  
  2907.     
  2908.     def on_troubleshoot_activate(self, widget):
  2909.         if not self.__dict__.has_key('troubleshooter'):
  2910.             self.troubleshooter = troubleshoot.run(self.on_troubleshoot_quit)
  2911.         
  2912.  
  2913.     
  2914.     def on_troubleshoot_quit(self, troubleshooter):
  2915.         del self.troubleshooter
  2916.  
  2917.     
  2918.     def on_save_as_group_activate(self, UNUSED):
  2919.         model = self.dests_iconview.get_model()
  2920.         printer_queues = []
  2921.         for object in model:
  2922.             printer_queues.append(object[2])
  2923.         
  2924.         self.groups_pane.create_new_group(printer_queues, self.current_filter_text)
  2925.  
  2926.     
  2927.     def on_save_as_search_group_activate(self, UNUSED):
  2928.         criterion = None
  2929.         if self.current_filter_mode == 'filter-name':
  2930.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_NAME, value = self.current_filter_text)
  2931.         elif self.current_filter_mode == 'filter-description':
  2932.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_DESC, value = self.current_filter_text)
  2933.         elif self.current_filter_mode == 'filter-location':
  2934.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_LOCATION, value = self.current_filter_text)
  2935.         elif self.current_filter_mode == 'filter-manufacturer':
  2936.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_MANUF, value = self.current_filter_text)
  2937.         else:
  2938.             nonfatalException()
  2939.             return None
  2940.         (self.current_filter_mode == 'filter-name').groups_pane.create_new_search_group(criterion, self.current_filter_text)
  2941.  
  2942.     
  2943.     def on_about_activate(self, widget):
  2944.         self.AboutDialog.set_transient_for(self.PrintersWindow)
  2945.         self.AboutDialog.run()
  2946.         self.AboutDialog.hide()
  2947.  
  2948.     
  2949.     def fillServerTab(self):
  2950.         self.changed = set()
  2951.         self.cups._begin_operation(_('fetching server settings'))
  2952.         
  2953.         try:
  2954.             self.server_settings = self.cups.adminGetServerSettings()
  2955.         except cups.IPPError:
  2956.             (e, m) = None
  2957.             show_IPP_Error(e, m, self.PrintersWindow)
  2958.             self.cups._end_operation()
  2959.             raise 
  2960.  
  2961.         self.cups._end_operation()
  2962.         for widget, setting in [
  2963.             (self.chkServerBrowse, cups.CUPS_SERVER_REMOTE_PRINTERS),
  2964.             (self.chkServerShare, cups.CUPS_SERVER_SHARE_PRINTERS),
  2965.             (self.chkServerShareAny, try_CUPS_SERVER_REMOTE_ANY),
  2966.             (self.chkServerRemoteAdmin, cups.CUPS_SERVER_REMOTE_ADMIN),
  2967.             (self.chkServerAllowCancelAll, cups.CUPS_SERVER_USER_CANCEL_ANY),
  2968.             (self.chkServerLogDebug, cups.CUPS_SERVER_DEBUG_LOGGING)]:
  2969.             widget.set_data('setting', setting)
  2970.             if self.server_settings.has_key(setting):
  2971.                 widget.set_active(int(self.server_settings[setting]))
  2972.                 widget.set_sensitive(True)
  2973.                 continue
  2974.             widget.set_active(False)
  2975.             widget.set_sensitive(False)
  2976.         
  2977.         self.setDataButtonState()
  2978.         
  2979.         try:
  2980.             flag = cups.CUPS_SERVER_SHARE_PRINTERS
  2981.             publishing = int(self.server_settings[flag])
  2982.             self.server_is_publishing = publishing
  2983.         except AttributeError:
  2984.             pass
  2985.  
  2986.         self.on_server_changed(self.chkServerShare)
  2987.  
  2988.     
  2989.     def on_server_changed(self, widget):
  2990.         setting = widget.get_data('setting')
  2991.         if self.server_settings.has_key(setting):
  2992.             if str(int(widget.get_active())) == self.server_settings[setting]:
  2993.                 self.changed.discard(widget)
  2994.             else:
  2995.                 self.changed.add(widget)
  2996.         
  2997.         sharing = self.chkServerShare.get_active()
  2998.         if sharing:
  2999.             pass
  3000.         self.chkServerShareAny.set_sensitive(self.server_settings.has_key(try_CUPS_SERVER_REMOTE_ANY))
  3001.         self.setDataButtonState()
  3002.  
  3003.     
  3004.     def save_serversettings(self):
  3005.         setting_dict = self.server_settings.copy()
  3006.         for widget, setting in [
  3007.             (self.chkServerBrowse, cups.CUPS_SERVER_REMOTE_PRINTERS),
  3008.             (self.chkServerShare, cups.CUPS_SERVER_SHARE_PRINTERS),
  3009.             (self.chkServerShareAny, try_CUPS_SERVER_REMOTE_ANY),
  3010.             (self.chkServerRemoteAdmin, cups.CUPS_SERVER_REMOTE_ADMIN),
  3011.             (self.chkServerAllowCancelAll, cups.CUPS_SERVER_USER_CANCEL_ANY),
  3012.             (self.chkServerLogDebug, cups.CUPS_SERVER_DEBUG_LOGGING)]:
  3013.             if not self.server_settings.has_key(setting):
  3014.                 continue
  3015.             
  3016.             setting_dict[setting] = str(int(widget.get_active()))
  3017.         
  3018.         self.cups._begin_operation(_('modifying server settings'))
  3019.         
  3020.         try:
  3021.             self.cups.adminSetServerSettings(setting_dict)
  3022.         except cups.IPPError:
  3023.             (e, m) = None
  3024.             show_IPP_Error(e, m, self.ServerSettingsDialog)
  3025.             self.cups._end_operation()
  3026.             return True
  3027.             except RuntimeError:
  3028.                 s = None
  3029.                 show_IPP_Error(None, s, self.ServerSettingsDialog)
  3030.                 self.cups._end_operation()
  3031.                 return True
  3032.             else:
  3033.                 self.cups._end_operation()
  3034.                 self.changed = set()
  3035.                 self.setDataButtonState()
  3036.                 old_setting = self.server_settings.get(cups.CUPS_SERVER_SHARE_PRINTERS, '0')
  3037.                 new_setting = setting_dict.get(cups.CUPS_SERVER_SHARE_PRINTERS, '0')
  3038.                 if 0 and old_setting == '0' and new_setting != '0':
  3039.                     show_info_dialog(_('Review Firewall'), _('You may need to adjust the firewall to allow network printing to this computer.') + '\n\n' + TEXT_start_firewall_tool, parent = self.ServerSettingsDialog)
  3040.                 
  3041.  
  3042.         time.sleep(1)
  3043.         self.reconnect()
  3044.         
  3045.         try:
  3046.             self.fillServerTab()
  3047.         except:
  3048.             nonfatalException()
  3049.  
  3050.  
  3051.     
  3052.     def on_problems_button_clicked(self, *args):
  3053.         if not self.__dict__.has_key('troubleshooter'):
  3054.             self.troubleshooter = troubleshoot.run(self.on_troubleshoot_quit, parent = self.ServerSettingsDialog)
  3055.         
  3056.  
  3057.     
  3058.     def on_new_printer_activate(self, widget):
  3059.         self.busy(self.PrintersWindow)
  3060.         self.newPrinterGUI.init('printer')
  3061.         self.ready(self.PrintersWindow)
  3062.  
  3063.     
  3064.     def on_autodetected_printer_without_driver(self, widget):
  3065.         self.busy(self.PrintersWindow)
  3066.         self.newPrinterGUI.init('printer_with_uri')
  3067.         self.ready(self.PrintersWindow)
  3068.  
  3069.     
  3070.     def on_new_class_activate(self, widget):
  3071.         self.newPrinterGUI.init('class')
  3072.  
  3073.     
  3074.     def on_btnSelectDevice_clicked(self, button):
  3075.         self.busy(self.PrintersWindow)
  3076.         self.newPrinterGUI.init('device')
  3077.         self.ready(self.PrintersWindow)
  3078.  
  3079.     
  3080.     def on_btnChangePPD_clicked(self, button):
  3081.         self.busy(self.PrintersWindow)
  3082.         self.newPrinterGUI.init('ppd')
  3083.         self.ready(self.PrintersWindow)
  3084.  
  3085.     
  3086.     def checkNPName(self, name):
  3087.         if not name:
  3088.             return False
  3089.         name = unicode(name.lower())
  3090.         for printer in self.printers.values():
  3091.             if not (printer.discovered) and printer.name.lower() == name:
  3092.                 return False
  3093.         
  3094.         return True
  3095.  
  3096.     
  3097.     def makeNameUnique(self, name):
  3098.         '''Make a suggested queue name valid and unique.'''
  3099.         name = name.replace(' ', '-')
  3100.         name = name.replace('/', '-')
  3101.         name = name.replace('#', '-')
  3102.         if not self.checkNPName(name):
  3103.             suffix = 2
  3104.             while not self.checkNPName(name + str(suffix)):
  3105.                 suffix += 1
  3106.                 if suffix == 100:
  3107.                     break
  3108.                     continue
  3109.             name += str(suffix)
  3110.         
  3111.         return name
  3112.  
  3113.     
  3114.     def printer_added_or_removed(self):
  3115.         gtk.gdk.threads_enter()
  3116.         self.populateList(prompt_allowed = False)
  3117.         gtk.gdk.threads_leave()
  3118.  
  3119.     
  3120.     def printer_added(self, mon, printer):
  3121.         monitor.Watcher.printer_added(self, mon, printer)
  3122.         self.printer_added_or_removed()
  3123.  
  3124.     
  3125.     def printer_event(self, mon, printer, eventname, event):
  3126.         monitor.Watcher.printer_event(self, mon, printer, eventname, event)
  3127.         gtk.gdk.threads_enter()
  3128.         if self.PrinterPropertiesDialog.get_property('visible'):
  3129.             self.printer.getAttributes()
  3130.             self.updatePrinterProperties()
  3131.         
  3132.         gtk.gdk.threads_leave()
  3133.  
  3134.     
  3135.     def printer_removed(self, mon, printer):
  3136.         monitor.Watcher.printer_removed(self, mon, printer)
  3137.         self.printer_added_or_removed()
  3138.  
  3139.     
  3140.     def state_reason_added(self, mon, reason):
  3141.         monitor.Watcher.state_reason_added(self, mon, reason)
  3142.         gtk.gdk.threads_enter()
  3143.         if self.PrinterPropertiesDialog.get_property('visible'):
  3144.             self.printer.getAttributes()
  3145.             self.updatePrinterProperties()
  3146.         
  3147.         gtk.gdk.threads_leave()
  3148.  
  3149.     
  3150.     def state_reason_removed(self, mon, reason):
  3151.         monitor.Watcher.state_reason_removed(self, mon, reason)
  3152.         gtk.gdk.threads_enter()
  3153.         if self.PrinterPropertiesDialog.get_property('visible'):
  3154.             self.printer.getAttributes()
  3155.             self.updatePrinterProperties()
  3156.         
  3157.         gtk.gdk.threads_leave()
  3158.  
  3159.     
  3160.     def cups_connection_error(self, mon):
  3161.         monitor.Watcher.cups_connection_error(self, mon)
  3162.         
  3163.         try:
  3164.             self.cups.getClasses()
  3165.         except:
  3166.             self.cups = None
  3167.             gtk.gdk.threads_enter()
  3168.             self.setConnected()
  3169.             self.populateList(prompt_allowed = False)
  3170.             gtk.gdk.threads_leave()
  3171.  
  3172.  
  3173.  
  3174.  
  3175. class NewPrinterGUI(GtkGUI):
  3176.     new_printer_device_tabs = {
  3177.         'parallel': 0,
  3178.         'usb': 0,
  3179.         'hal': 0,
  3180.         'beh': 0,
  3181.         'hp': 8,
  3182.         'hpfax': 0,
  3183.         'socket': 2,
  3184.         'ipp': 3,
  3185.         'http': 3,
  3186.         'lpd': 4,
  3187.         'scsi': 5,
  3188.         'serial': 6,
  3189.         'smb': 7,
  3190.         'network': 9 }
  3191.     DOWNLOADABLE_ONLYPPD = True
  3192.     HP_PLUGIN_SUPPORT = True
  3193.     
  3194.     def __init__(self, mainapp):
  3195.         self.mainapp = mainapp
  3196.         self.tooltips = mainapp.tooltips
  3197.         self.language = mainapp.language
  3198.         self.options = { }
  3199.         self.changed = set()
  3200.         self.conflicts = set()
  3201.         self.ppd = None
  3202.         self.remotecupsqueue = False
  3203.         self.exactdrivermatch = False
  3204.         self.installable_options = False
  3205.         self.jockey_installed_files = []
  3206.         self.jockey_lock = thread.allocate_lock()
  3207.         self.ppds_lock = thread.allocate_lock()
  3208.         self.ipp_lock = thread.allocate_lock()
  3209.         self.drivers_lock = thread.allocate_lock()
  3210.         self.getWidgets({
  3211.             'NewPrinterWindow': [
  3212.                 'NewPrinterWindow',
  3213.                 'ntbkNewPrinter',
  3214.                 'btnNPBack',
  3215.                 'btnNPForward',
  3216.                 'btnNPApply',
  3217.                 'entNPName',
  3218.                 'entNPDescription',
  3219.                 'entNPLocation',
  3220.                 'tvNPDevices',
  3221.                 'ntbkNPType',
  3222.                 'lblNPDeviceDescription',
  3223.                 'expNPDeviceURIs',
  3224.                 'tvNPDeviceURIs',
  3225.                 'cmbNPTSerialBaud',
  3226.                 'cmbNPTSerialParity',
  3227.                 'cmbNPTSerialBits',
  3228.                 'cmbNPTSerialFlow',
  3229.                 'cmbentNPTLpdHost',
  3230.                 'cmbentNPTLpdQueue',
  3231.                 'entNPTIPPHostname',
  3232.                 'btnIPPFindQueue',
  3233.                 'lblIPPURI',
  3234.                 'entNPTIPPQueuename',
  3235.                 'btnIPPVerify',
  3236.                 'entNPTDirectJetHostname',
  3237.                 'entNPTDirectJetPort',
  3238.                 'entSMBURI',
  3239.                 'btnSMBBrowse',
  3240.                 'tblSMBAuth',
  3241.                 'rbtnSMBAuthPrompt',
  3242.                 'rbtnSMBAuthSet',
  3243.                 'entSMBUsername',
  3244.                 'entSMBPassword',
  3245.                 'btnSMBVerify',
  3246.                 'entNPTHPHostname',
  3247.                 'btnHPFindQueue',
  3248.                 'entNPTNetworkHostname',
  3249.                 'btnNetworkFind',
  3250.                 'lblHPURI',
  3251.                 'entNPTDevice',
  3252.                 'tvNCMembers',
  3253.                 'tvNCNotMembers',
  3254.                 'ntbkPPDSource',
  3255.                 'rbtnNPPPD',
  3256.                 'tvNPMakes',
  3257.                 'rbtnNPFoomatic',
  3258.                 'filechooserPPD',
  3259.                 'rbtnNPDownloadableDriverSearch',
  3260.                 'entNPDownloadableDriverSearch',
  3261.                 'btnNPDownloadableDriverSearch',
  3262.                 'cmbNPDownloadableDriverFoundPrinters',
  3263.                 'tvNPModels',
  3264.                 'tvNPDrivers',
  3265.                 'rbtnChangePPDasIs',
  3266.                 'rbtnChangePPDKeepSettings',
  3267.                 'scrNPInstallableOptions',
  3268.                 'vbNPInstallOptions',
  3269.                 'tvNPDownloadableDrivers',
  3270.                 'ntbkNPDownloadableDriverProperties',
  3271.                 'lblNPDownloadableDriverSupplier',
  3272.                 'cbNPDownloadableDriverSupplierVendor',
  3273.                 'lblNPDownloadableDriverLicense',
  3274.                 'cbNPDownloadableDriverLicensePatents',
  3275.                 'cbNPDownloadableDriverLicenseFree',
  3276.                 'lblNPDownloadableDriverDescription',
  3277.                 'lblNPDownloadableDriverSupportContacts',
  3278.                 'hsDownloadableDriverPerfText',
  3279.                 'hsDownloadableDriverPerfLineArt',
  3280.                 'hsDownloadableDriverPerfGraphics',
  3281.                 'hsDownloadableDriverPerfPhoto',
  3282.                 'lblDownloadableDriverPerfTextUnknown',
  3283.                 'lblDownloadableDriverPerfLineArtUnknown',
  3284.                 'lblDownloadableDriverPerfGraphicsUnknown',
  3285.                 'lblDownloadableDriverPerfPhotoUnknown',
  3286.                 'frmNPDownloadableDriverLicenseTerms',
  3287.                 'tvNPDownloadableDriverLicense',
  3288.                 'rbtnNPDownloadLicenseYes',
  3289.                 'rbtnNPDownloadLicenseNo'],
  3290.             'IPPBrowseDialog': [
  3291.                 'IPPBrowseDialog',
  3292.                 'tvIPPBrowser',
  3293.                 'btnIPPBrowseOk'],
  3294.             'SMBBrowseDialog': [
  3295.                 'SMBBrowseDialog',
  3296.                 'tvSMBBrowser',
  3297.                 'btnSMBBrowseOk'],
  3298.             'InstallDialog': [
  3299.                 'InstallDialog',
  3300.                 'lblInstall'] })
  3301.         for dialog in [
  3302.             self.IPPBrowseDialog,
  3303.             self.SMBBrowseDialog]:
  3304.             dialog.connect('delete-event', on_delete_just_hide)
  3305.         
  3306.         self.WaitWindow = mainapp.WaitWindow
  3307.         self.lblWait = mainapp.lblWait
  3308.         self.busy = mainapp.busy
  3309.         self.ready = mainapp.ready
  3310.         gtk_label_autowrap.set_autowrap(self.NewPrinterWindow)
  3311.         self.ntbkNewPrinter.set_show_tabs(False)
  3312.         self.ntbkPPDSource.set_show_tabs(False)
  3313.         self.ntbkNPType.set_show_tabs(False)
  3314.         self.ntbkNPDownloadableDriverProperties.set_show_tabs(False)
  3315.         self.openprinting = cupshelpers.openprinting.OpenPrinting()
  3316.         self.openprinting_query_handle = None
  3317.         combobox = self.cmbNPDownloadableDriverFoundPrinters
  3318.         cell = gtk.CellRendererText()
  3319.         combobox.pack_start(cell, True)
  3320.         combobox.add_attribute(cell, 'text', 0)
  3321.         if self.DOWNLOADABLE_ONLYPPD:
  3322.             for widget in [
  3323.                 self.cbNPDownloadableDriverLicenseFree,
  3324.                 self.cbNPDownloadableDriverLicensePatents]:
  3325.                 widget.hide()
  3326.             
  3327.         
  3328.         
  3329.         def protect_toggle(toggle_widget):
  3330.             active = toggle_widget.get_data('protect_active')
  3331.             if active != None:
  3332.                 toggle_widget.set_active(active)
  3333.             
  3334.  
  3335.         for widget in [
  3336.             self.cbNPDownloadableDriverSupplierVendor,
  3337.             self.cbNPDownloadableDriverLicenseFree,
  3338.             self.cbNPDownloadableDriverLicensePatents]:
  3339.             widget.connect('clicked', protect_toggle)
  3340.         
  3341.         for widget in [
  3342.             self.hsDownloadableDriverPerfText,
  3343.             self.hsDownloadableDriverPerfLineArt,
  3344.             self.hsDownloadableDriverPerfGraphics,
  3345.             self.hsDownloadableDriverPerfPhoto]:
  3346.             widget.connect('change-value', (lambda x, y, z: True))
  3347.         
  3348.         slct = self.tvNPDevices.get_selection()
  3349.         slct.set_select_function(self.device_select_function)
  3350.         self.tvNPDevices.set_row_separator_func(self.device_row_separator_fn)
  3351.         self.tvNPDevices.connect('row-activated', self.device_row_activated)
  3352.         self.expNPDeviceURIs.connect('notify::expanded', self.on_expNPDeviceURIs_expanded)
  3353.         self.smb_store = gtk.TreeStore(gobject.TYPE_PYOBJECT)
  3354.         self.btnSMBBrowse.set_sensitive(PYSMB_AVAILABLE)
  3355.         if not PYSMB_AVAILABLE:
  3356.             self.btnSMBBrowse.set_tooltip_text(_('Browsing not available (pysmbc not installed)'))
  3357.         
  3358.         self.tvSMBBrowser.set_model(self.smb_store)
  3359.         col = gtk.TreeViewColumn(_('Share'))
  3360.         cell = gtk.CellRendererText()
  3361.         col.pack_start(cell, False)
  3362.         col.set_cell_data_func(cell, self.smbbrowser_cell_share)
  3363.         self.tvSMBBrowser.append_column(col)
  3364.         col = gtk.TreeViewColumn(_('Comment'))
  3365.         cell = gtk.CellRendererText()
  3366.         col.pack_start(cell, False)
  3367.         col.set_cell_data_func(cell, self.smbbrowser_cell_comment)
  3368.         self.tvSMBBrowser.append_column(col)
  3369.         slct = self.tvSMBBrowser.get_selection()
  3370.         slct.set_select_function(self.smb_select_function)
  3371.         self.SMBBrowseDialog.set_transient_for(self.NewPrinterWindow)
  3372.         self.ipp_store = gtk.TreeStore(str, str, gobject.TYPE_PYOBJECT)
  3373.         self.tvIPPBrowser.set_model(self.ipp_store)
  3374.         self.ipp_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
  3375.         col = gtk.TreeViewColumn(_('Queue'), gtk.CellRendererText(), text = 0)
  3376.         col.set_resizable(True)
  3377.         col.set_sort_column_id(0)
  3378.         self.tvIPPBrowser.append_column(col)
  3379.         col = gtk.TreeViewColumn(_('Location'), gtk.CellRendererText(), text = 1)
  3380.         self.tvIPPBrowser.append_column(col)
  3381.         self.IPPBrowseDialog.set_transient_for(self.NewPrinterWindow)
  3382.         self.tvNPDriversTooltips = TreeViewTooltips(self.tvNPDrivers, self.NPDriversTooltips)
  3383.         ppd_filter = gtk.FileFilter()
  3384.         ppd_filter.set_name(_('PostScript Printer Description files (*.ppd, *.PPD, *.ppd.gz, *.PPD.gz, *.PPD.GZ)'))
  3385.         ppd_filter.add_pattern('*.ppd')
  3386.         ppd_filter.add_pattern('*.PPD')
  3387.         ppd_filter.add_pattern('*.ppd.gz')
  3388.         ppd_filter.add_pattern('*.PPD.gz')
  3389.         ppd_filter.add_pattern('*.PPD.GZ')
  3390.         self.filechooserPPD.add_filter(ppd_filter)
  3391.         ppd_filter = gtk.FileFilter()
  3392.         ppd_filter.set_name(_('All files (*)'))
  3393.         ppd_filter.add_pattern('*')
  3394.         self.filechooserPPD.add_filter(ppd_filter)
  3395.  
  3396.     
  3397.     def show_IPP_Error(self, exception, message):
  3398.         return show_IPP_Error(exception, message, parent = self.NewPrinterWindow)
  3399.  
  3400.     
  3401.     def option_changed(self, option):
  3402.         if option.is_changed():
  3403.             self.changed.add(option)
  3404.         else:
  3405.             self.changed.discard(option)
  3406.         if option.conflicts:
  3407.             self.conflicts.add(option)
  3408.         else:
  3409.             self.conflicts.discard(option)
  3410.         self.setDataButtonState()
  3411.  
  3412.     
  3413.     def setDataButtonState(self):
  3414.         self.btnNPForward.set_sensitive(not bool(self.conflicts))
  3415.  
  3416.     
  3417.     def init(self, dialog_mode):
  3418.         self.dialog_mode = dialog_mode
  3419.         self.options = { }
  3420.         self.changed = set()
  3421.         self.conflicts = set()
  3422.         combobox = self.cmbNPDownloadableDriverFoundPrinters
  3423.         combobox.set_model(gtk.ListStore(str, str))
  3424.         self.entNPDownloadableDriverSearch.set_text('')
  3425.         button = self.btnNPDownloadableDriverSearch
  3426.         label = button.get_children()[0].get_children()[0].get_children()[1]
  3427.         self.btnNPDownloadableDriverSearch_label = label
  3428.         label.set_text(_('Search'))
  3429.         if self.dialog_mode in ('printer', 'printer_with_uri', 'class'):
  3430.             if self.dialog_mode == 'class':
  3431.                 name_proto = 'class'
  3432.             else:
  3433.                 name_proto = 'printer'
  3434.             self.entNPName.set_text(self.mainapp.makeNameUnique(name_proto))
  3435.             self.entNPName.grab_focus()
  3436.             for widget in [
  3437.                 self.entNPLocation,
  3438.                 self.entNPDescription,
  3439.                 self.entSMBURI,
  3440.                 self.entSMBUsername,
  3441.                 self.entSMBPassword]:
  3442.                 widget.set_text('')
  3443.             
  3444.         
  3445.         if self.dialog_mode == 'printer_with_uri':
  3446.             device_dict = { }
  3447.             self.device = cupshelpers.Device(self.mainapp.device_uri, **device_dict)
  3448.         
  3449.         self.entNPTDirectJetPort.set_text('9100')
  3450.         if self.dialog_mode == 'printer':
  3451.             self.NewPrinterWindow.set_title(_('New Printer'))
  3452.             self.ntbkNewPrinter.set_current_page(1)
  3453.             self.fillDeviceTab()
  3454.             self.rbtnNPFoomatic.set_active(True)
  3455.             self.on_rbtnNPFoomatic_toggled(self.rbtnNPFoomatic)
  3456.             self.new_printer_PPDs_loaded = False
  3457.             self.queryPPDs()
  3458.         elif self.dialog_mode == 'class':
  3459.             self.NewPrinterWindow.set_title(_('New Class'))
  3460.             self.fillNewClassMembers()
  3461.             self.ntbkNewPrinter.set_current_page(0)
  3462.         elif self.dialog_mode == 'device':
  3463.             self.NewPrinterWindow.set_title(_('Change Device URI'))
  3464.             self.ntbkNewPrinter.set_current_page(1)
  3465.             self.fillDeviceTab(self.mainapp.printer.device_uri)
  3466.         elif self.dialog_mode == 'ppd' or self.dialog_mode == 'printer_with_uri':
  3467.             if self.dialog_mode == 'ppd':
  3468.                 self.NewPrinterWindow.set_title(_('Change Driver'))
  3469.             else:
  3470.                 self.NewPrinterWindow.set_title(_('New Printer'))
  3471.             self.ntbkNewPrinter.set_current_page(2)
  3472.             self.rbtnNPFoomatic.set_active(True)
  3473.             self.on_rbtnNPFoomatic_toggled(self.rbtnNPFoomatic)
  3474.             self.rbtnChangePPDKeepSettings.set_active(True)
  3475.             self.auto_model = ''
  3476.             ppd = self.mainapp.ppd
  3477.             devid = self.mainapp.devid
  3478.             if devid != '':
  3479.                 
  3480.                 try:
  3481.                     devid_dict = cupshelpers.parseDeviceID(devid)
  3482.                     self.loadPPDs()
  3483.                     reloaded = 0
  3484.                     while reloaded < 2:
  3485.                         (status, ppdname) = self.ppds.getPPDNameFromDeviceID(devid_dict['MFG'], devid_dict['MDL'], devid_dict['DES'], devid_dict['CMD'], uri, self.jockey_installed_files)
  3486.                         if status != self.ppds.STATUS_SUCCESS and reloaded == 0:
  3487.                             if self.fetchJockeyDriver():
  3488.                                 
  3489.                                 try:
  3490.                                     self.dropPPDs()
  3491.                                     self.loadPPDs()
  3492.                                     reloaded = 1
  3493.                                 reloaded = 2
  3494.  
  3495.                             else:
  3496.                                 reloaded = 2
  3497.                         self.fetchJockeyDriver()
  3498.                         reloaded = 2
  3499.                         continue
  3500.                         None if self.dialog_mode == 'ppd' else self.install_hplip_plugin(uri)
  3501.                     if ppdname:
  3502.                         ppddict = self.ppds.getInfoFromPPDName(ppdname)
  3503.                         make_model = ppddict['ppd-make-and-model']
  3504.                         (self.auto_make, self.auto_model) = cupshelpers.ppds.ppdMakeModelSplit(make_model)
  3505.                         if status == self.ppds.STATUS_SUCCESS and self.dialog_mode != 'ppd':
  3506.                             self.exactdrivermatch = True
  3507.                             self.fillMakeList()
  3508.                             self.ntbkNewPrinter.set_current_page(6)
  3509.                             self.nextNPTab(step = 0)
  3510.                         else:
  3511.                             self.exactdrivermatch = False
  3512.                     else:
  3513.                         self.auto_make = devid_dict['MFG']
  3514.                         self.auto_model = devid_dict['MDL']
  3515.                 except:
  3516.                     None if self.dialog_mode == 'ppd' else self.install_hplip_plugin(uri)
  3517.                     self.auto_make = devid_dict['MFG']
  3518.                     self.auto_model = devid_dict['MDL']
  3519.  
  3520.                 self.mainapp.devid = ''
  3521.             elif ppd:
  3522.                 attr = ppd.findAttr('Manufacturer')
  3523.                 if attr:
  3524.                     mfr = attr.value
  3525.                 else:
  3526.                     mfr = ''
  3527.                 makeandmodel = mfr
  3528.                 attr = ppd.findAttr('ModelName')
  3529.                 if not attr:
  3530.                     attr = ppd.findAttr('ShortNickName')
  3531.                 
  3532.                 if not attr:
  3533.                     attr = ppd.findAttr('NickName')
  3534.                 
  3535.                 if attr:
  3536.                     if attr.value.startswith(mfr):
  3537.                         makeandmodel = attr.value
  3538.                     else:
  3539.                         makeandmodel += ' ' + attr.value
  3540.                 else:
  3541.                     makeandmodel = ''
  3542.                 (self.auto_make, self.auto_model) = cupshelpers.ppds.ppdMakeModelSplit(makeandmodel)
  3543.             else:
  3544.                 self.auto_make = 'Raw'
  3545.                 self.auto_model = 'Queue'
  3546.             
  3547.             try:
  3548.                 self.loadPPDs()
  3549.             except cups.IPPError:
  3550.                 (e, m) = None
  3551.                 show_IPP_Error(e, m, parent = self.mainapp.PrintersWindow)
  3552.                 return None
  3553.                 return None
  3554.  
  3555.             self.fillMakeList()
  3556.         
  3557.         self.setNPButtons()
  3558.         self.NewPrinterWindow.show()
  3559.  
  3560.     
  3561.     def queryJockeyDriver(self):
  3562.         debugprint('queryJockeyDriver')
  3563.         if not self.jockey_lock.acquire(0):
  3564.             debugprint('queryJockeyDriver: in progress')
  3565.             return None
  3566.         debugprint('Lock acquired for Jockey driver thread')
  3567.         devid = ''
  3568.         
  3569.         try:
  3570.             devid = self.device.id
  3571.         except:
  3572.             self.jockey_lock.acquire(0)
  3573.  
  3574.         if devid == '':
  3575.             self.jockey_lock.release()
  3576.             return None
  3577.         thread.start_new_thread(self.getJockeyDriver_thread, (devid,))
  3578.         debugprint('Jockey driver thread started')
  3579.  
  3580.     
  3581.     def getJockeyDriver_thread(self, id):
  3582.         debugprint('Requesting driver from Jockey: %s' % id)
  3583.         self.jockey_driver_result = False
  3584.         self.jockey_installed_files = []
  3585.         
  3586.         try:
  3587.             bus = dbus.SessionBus()
  3588.             obj = bus.get_object('com.ubuntu.DeviceDriver', '/GUI')
  3589.             jockeyloader = dbus.Interface(obj, 'com.ubuntu.DeviceDriver')
  3590.             (result, installedfiles) = jockeyloader.search_driver('printer_deviceid:%s' % id, timeout = 999999)
  3591.             self.jockey_driver_result = result
  3592.             self.jockey_installed_files = installedfiles
  3593.             if result:
  3594.                 debugprint('New driver downloaded and installed')
  3595.             else:
  3596.                 debugprint('No new driver found or download rejected')
  3597.         except dbus.DBusException:
  3598.             e = None
  3599.             self.jockey_driver_result = 'D-Bus Error: %s' % e
  3600.             debugprint(self.jockey_driver_result)
  3601.         except Exception:
  3602.             e = None
  3603.             nonfatalException()
  3604.             self.jockey_driver_result = e
  3605.             debugprint('Non-D-Bus error on Jockey call: %s' % e)
  3606.  
  3607.         debugprint('Releasing Jockey driver lock')
  3608.         self.jockey_lock.release()
  3609.  
  3610.     
  3611.     def fetchJockeyDriver(self, parent = None):
  3612.         debugprint('fetchJockeyDriver')
  3613.         self.queryJockeyDriver()
  3614.         time.sleep(0.1)
  3615.         waiting = False
  3616.         while self.jockey_lock.locked():
  3617.             if not waiting:
  3618.                 waiting = True
  3619.                 self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for downloadable drivers'))
  3620.                 if not parent:
  3621.                     parent = self.mainapp.PrintersWindow
  3622.                 
  3623.                 self.WaitWindow.set_transient_for(parent)
  3624.                 self.WaitWindow.show()
  3625.             
  3626.             while gtk.events_pending():
  3627.                 gtk.main_iteration()
  3628.             time.sleep(0.1)
  3629.         if waiting:
  3630.             self.WaitWindow.hide()
  3631.         
  3632.         debugprint('Driver download request finished')
  3633.         result = self.jockey_driver_result
  3634.         if isinstance(result, Exception):
  3635.             raise result
  3636.         isinstance(result, Exception)
  3637.         return result
  3638.  
  3639.     
  3640.     def queryPPDs(self):
  3641.         debugprint('queryPPDs')
  3642.         if not self.ppds_lock.acquire(0):
  3643.             debugprint('queryPPDs: in progress')
  3644.             return None
  3645.         debugprint('Lock acquired for PPDs thread')
  3646.         thread.start_new_thread(self.getPPDs_thread, (self.language[0],))
  3647.         debugprint('PPDs thread started')
  3648.  
  3649.     
  3650.     def getPPDs_thread(self, language):
  3651.         
  3652.         try:
  3653.             debugprint('Connecting (PPDs)')
  3654.             cups.setUser(self.mainapp.connect_user)
  3655.             cups.setPasswordCB((lambda x: ''))
  3656.             c = cups.Connection(host = self.mainapp.connect_server, encryption = self.mainapp.connect_encrypt)
  3657.             debugprint('Fetching PPDs')
  3658.             ppds_dict = c.getPPDs()
  3659.             self.ppds_result = cupshelpers.ppds.PPDs(ppds_dict, language = language)
  3660.             debugprint('Closing connection (PPDs)')
  3661.             del c
  3662.         except cups.IPPError:
  3663.             (e, msg) = None
  3664.             self.ppds_result = cups.IPPError(e, msg)
  3665.         except Exception:
  3666.             e = None
  3667.             nonfatalException()
  3668.             self.ppds_result = e
  3669.  
  3670.         debugprint('Releasing PPDs lock')
  3671.         self.ppds_lock.release()
  3672.  
  3673.     
  3674.     def fetchPPDs(self, parent = None):
  3675.         debugprint('fetchPPDs')
  3676.         self.queryPPDs()
  3677.         waiting = False
  3678.         while self.ppds_lock.locked():
  3679.             if not waiting:
  3680.                 waiting = True
  3681.                 self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for drivers'))
  3682.                 if not parent:
  3683.                     parent = self.mainapp.PrintersWindow
  3684.                 
  3685.                 self.WaitWindow.set_transient_for(parent)
  3686.                 self.WaitWindow.show_now()
  3687.             
  3688.             while gtk.events_pending():
  3689.                 gtk.main_iteration()
  3690.             time.sleep(0.1)
  3691.         if waiting:
  3692.             self.WaitWindow.hide()
  3693.         
  3694.         debugprint('Got PPDs')
  3695.         result = self.ppds_result
  3696.         if isinstance(result, Exception):
  3697.             raise result
  3698.         isinstance(result, Exception)
  3699.         return result
  3700.  
  3701.     
  3702.     def loadPPDs(self, parent = None):
  3703.         
  3704.         try:
  3705.             return self.ppds
  3706.         except:
  3707.             self.ppds = self.fetchPPDs(parent = parent)
  3708.             return self.ppds
  3709.  
  3710.  
  3711.     
  3712.     def dropPPDs(self):
  3713.         
  3714.         try:
  3715.             del self.ppds
  3716.         except:
  3717.             pass
  3718.  
  3719.  
  3720.     
  3721.     def fillNewClassMembers(self):
  3722.         model = self.tvNCMembers.get_model()
  3723.         model.clear()
  3724.         model = self.tvNCNotMembers.get_model()
  3725.         model.clear()
  3726.         for printer in self.mainapp.printers.itervalues():
  3727.             model.append((printer.name,))
  3728.         
  3729.  
  3730.     
  3731.     def on_btnNCAddMember_clicked(self, button):
  3732.         moveClassMembers(self.tvNCNotMembers, self.tvNCMembers)
  3733.         self.btnNPApply.set_sensitive(bool(getCurrentClassMembers(self.tvNCMembers)))
  3734.  
  3735.     
  3736.     def on_btnNCDelMember_clicked(self, button):
  3737.         moveClassMembers(self.tvNCMembers, self.tvNCNotMembers)
  3738.         self.btnNPApply.set_sensitive(bool(getCurrentClassMembers(self.tvNCMembers)))
  3739.  
  3740.     
  3741.     def on_NPCancel(self, widget, event = None):
  3742.         self.NewPrinterWindow.hide()
  3743.         if self.openprinting_query_handle != None:
  3744.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  3745.             self.openprinting_query_handle = None
  3746.         
  3747.         return True
  3748.  
  3749.     
  3750.     def on_btnNPBack_clicked(self, widget):
  3751.         self.nextNPTab(-1)
  3752.  
  3753.     
  3754.     def on_btnNPForward_clicked(self, widget):
  3755.         self.nextNPTab()
  3756.  
  3757.     
  3758.     def nextNPTab(self, step = 1):
  3759.         page_nr = self.ntbkNewPrinter.get_current_page()
  3760.         if self.dialog_mode == 'class':
  3761.             order = [
  3762.                 0,
  3763.                 4,
  3764.                 5]
  3765.         elif self.dialog_mode == 'printer' or self.dialog_mode == 'printer_with_uri':
  3766.             self.busy(self.NewPrinterWindow)
  3767.             if page_nr == 1:
  3768.                 (self.auto_make, self.auto_model) = (None, None)
  3769.                 self.device.uri = self.getDeviceURI()
  3770.                 if not self.install_hplip_plugin(self.device.uri):
  3771.                     self.on_NPCancel(None)
  3772.                     return None
  3773.                 uri = self.device.uri
  3774.                 if uri and uri.startswith('smb://'):
  3775.                     uri = SMBURI(uri = uri[6:]).sanitize_uri()
  3776.                 
  3777.                 self.remotecupsqueue = None
  3778.                 res = re.search('ipp://(\\S+(:\\d+|))/printers/(\\S+)', uri)
  3779.                 if res:
  3780.                     resg = res.groups()
  3781.                     
  3782.                     try:
  3783.                         conn = httplib.HTTPConnection(resg[0])
  3784.                         conn.request('GET', '/printers/%s.ppd' % resg[2])
  3785.                         resp = conn.getresponse()
  3786.                         if resp.status == 200:
  3787.                             self.remotecupsqueue = resg[2]
  3788.                     except:
  3789.                         pass
  3790.  
  3791.                     
  3792.                     try:
  3793.                         if len(resg[1]) > 0:
  3794.                             port = int(resg[1])
  3795.                         else:
  3796.                             port = 631
  3797.                         encryption = cups.HTTP_ENCRYPT_IF_REQUESTED
  3798.                         c = cups.Connection(host = resg[0], port = port, encryption = encryption)
  3799.                         r = [
  3800.                             'printer-info',
  3801.                             'printer-location']
  3802.                         attrs = c.getPrinterAttributes(uri = uri, requested_attributes = r)
  3803.                         info = attrs.get('printer-info', '')
  3804.                         location = attrs.get('printer-location', '')
  3805.                         if len(info) > 0:
  3806.                             self.entNPDescription.set_text(info)
  3807.                         
  3808.                         if len(location) > 0:
  3809.                             self.entNPLocation.set_text(location)
  3810.                     nonfatalException()
  3811.  
  3812.                 
  3813.                 if not (self.remotecupsqueue) and not (self.new_printer_PPDs_loaded):
  3814.                     
  3815.                     try:
  3816.                         self.loadPPDs(self.NewPrinterWindow)
  3817.                     except cups.IPPError:
  3818.                         (e, msg) = None
  3819.                         self.ready(self.NewPrinterWindow)
  3820.                         self.show_IPP_Error(e, msg)
  3821.                         return None
  3822.                         self.ready(self.NewPrinterWindow)
  3823.                         return None
  3824.  
  3825.                     self.new_printer_PPDs_loaded = True
  3826.                 
  3827.                 ppdname = None
  3828.                 
  3829.                 try:
  3830.                     if self.remotecupsqueue:
  3831.                         ppdname = 'raw'
  3832.                         self.ppd = ppdname
  3833.                         name = self.remotecupsqueue
  3834.                         name = self.mainapp.makeNameUnique(name)
  3835.                         self.entNPName.set_text(name)
  3836.                     elif self.device.id:
  3837.                         id_dict = self.device.id_dict
  3838.                         reloaded = 0
  3839.                         while reloaded < 2:
  3840.                             (status, ppdname) = self.ppds.getPPDNameFromDeviceID(id_dict['MFG'], id_dict['MDL'], id_dict['DES'], id_dict['CMD'], self.device.uri, self.jockey_installed_files)
  3841.                             if status != self.ppds.STATUS_SUCCESS and reloaded == 0:
  3842.                                 if self.fetchJockeyDriver():
  3843.                                     
  3844.                                     try:
  3845.                                         self.dropPPDs()
  3846.                                         self.loadPPDs()
  3847.                                         reloaded = 1
  3848.                                     reloaded = 2
  3849.  
  3850.                                 else:
  3851.                                     reloaded = 2
  3852.                             self.fetchJockeyDriver()
  3853.                             reloaded = 2
  3854.                     else:
  3855.                         (status, ppdname) = self.ppds.getPPDNameFromDeviceID('Generic', 'Printer', 'Generic Printer', [], self.device.uri)
  3856.                     if ppdname and not (self.remotecupsqueue):
  3857.                         ppddict = self.ppds.getInfoFromPPDName(ppdname)
  3858.                         make_model = ppddict['ppd-make-and-model']
  3859.                         (make, model) = cupshelpers.ppds.ppdMakeModelSplit(make_model)
  3860.                         self.auto_make = make
  3861.                         self.auto_model = model
  3862.                         if status == self.ppds.STATUS_SUCCESS and self.dialog_mode != 'ppd':
  3863.                             self.exactdrivermatch = True
  3864.                         else:
  3865.                             self.exactdrivermatch = False
  3866.                 except:
  3867.                     nonfatalException()
  3868.  
  3869.                 if not self.remotecupsqueue:
  3870.                     self.fillMakeList()
  3871.                 
  3872.             elif page_nr == 3:
  3873.                 if not self.device.id:
  3874.                     
  3875.                     try:
  3876.                         (model, iter) = self.tvNPModels.get_selection().get_selected()
  3877.                         name = model.get(iter, 0)[0]
  3878.                         name = self.mainapp.makeNameUnique(name)
  3879.                         self.entNPName.set_text(name)
  3880.                     nonfatalException()
  3881.  
  3882.                 
  3883.             
  3884.             self.ready(self.NewPrinterWindow)
  3885.             if self.dialog_mode == 'printer':
  3886.                 if self.remotecupsqueue:
  3887.                     order = [
  3888.                         1,
  3889.                         0]
  3890.                 elif self.exactdrivermatch:
  3891.                     order = [
  3892.                         1,
  3893.                         6,
  3894.                         0]
  3895.                 elif self.rbtnNPFoomatic.get_active():
  3896.                     order = [
  3897.                         1,
  3898.                         2,
  3899.                         3,
  3900.                         6,
  3901.                         0]
  3902.                 elif self.rbtnNPPPD.get_active():
  3903.                     order = [
  3904.                         1,
  3905.                         2,
  3906.                         6,
  3907.                         0]
  3908.                 else:
  3909.                     order = [
  3910.                         1,
  3911.                         2,
  3912.                         7,
  3913.                         6,
  3914.                         0]
  3915.             elif self.remotecupsqueue:
  3916.                 order = [
  3917.                     0]
  3918.             elif self.exactdrivermatch:
  3919.                 order = [
  3920.                     6,
  3921.                     0]
  3922.             elif self.rbtnNPFoomatic.get_active():
  3923.                 order = [
  3924.                     2,
  3925.                     3,
  3926.                     6,
  3927.                     0]
  3928.             elif self.rbtnNPPPD.get_active():
  3929.                 order = [
  3930.                     2,
  3931.                     6,
  3932.                     0]
  3933.             else:
  3934.                 order = [
  3935.                     2,
  3936.                     7,
  3937.                     6,
  3938.                     0]
  3939.         elif self.dialog_mode == 'device':
  3940.             order = [
  3941.                 1]
  3942.         elif self.dialog_mode == 'ppd':
  3943.             if self.rbtnNPFoomatic.get_active():
  3944.                 order = [
  3945.                     2,
  3946.                     3,
  3947.                     5,
  3948.                     6]
  3949.             elif self.rbtnNPPPD.get_active():
  3950.                 order = [
  3951.                     2,
  3952.                     5,
  3953.                     6]
  3954.             else:
  3955.                 order = [
  3956.                     2,
  3957.                     7,
  3958.                     5,
  3959.                     6]
  3960.         
  3961.         next_page_nr = order[order.index(page_nr) + step]
  3962.         fetch_ppd = False
  3963.         
  3964.         try:
  3965.             if order.index(5) > -1:
  3966.                 if next_page_nr == 5:
  3967.                     pass
  3968.                 fetch_ppd = step >= 0
  3969.         except ValueError:
  3970.             if next_page_nr == 6:
  3971.                 pass
  3972.             fetch_ppd = step >= 0
  3973.  
  3974.         debugprint('Will fetch ppd? %d' % fetch_ppd)
  3975.         if fetch_ppd:
  3976.             self.ppd = self.getNPPPD()
  3977.             self.installable_options = False
  3978.             if self.ppd == None:
  3979.                 return None
  3980.             if isinstance(self.ppd, cups.PPD):
  3981.                 self.fillNPInstallableOptions()
  3982.             else:
  3983.                 ppd = self.ppd
  3984.                 self.ppd = None
  3985.                 self.fillNPInstallableOptions()
  3986.                 self.ppd = ppd
  3987.             if not self.installable_options:
  3988.                 if next_page_nr == 6:
  3989.                     next_page_nr = order[order.index(next_page_nr) + 1]
  3990.                 
  3991.             
  3992.         
  3993.         if next_page_nr == 6 and not (self.installable_options) and step < 0:
  3994.             next_page_nr = order[order.index(next_page_nr) - 1]
  3995.         
  3996.         if step >= 0 and next_page_nr == 7:
  3997.             if self.drivers_lock.locked():
  3998.                 self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for drivers'))
  3999.                 self.WaitWindow.set_transient_for(self.NewPrinterWindow)
  4000.                 self.WaitWindow.show()
  4001.                 self.busy(self.NewPrinterWindow)
  4002.                 while self.drivers_lock.locked():
  4003.                     while gtk.events_pending():
  4004.                         gtk.main_iteration()
  4005.                     time.sleep(0.1)
  4006.                 self.ready(self.NewPrinterWindow)
  4007.                 self.WaitWindow.hide()
  4008.             
  4009.             self.fillDownloadableDrivers()
  4010.         
  4011.         if step >= 0 and next_page_nr == 0:
  4012.             name = None
  4013.             descr = None
  4014.             
  4015.             try:
  4016.                 if self.device.id and self.device.type not in ('socket', 'lpd', 'ipp', 'bluetooth'):
  4017.                     name = self.device.id_dict['MDL']
  4018.                     descr = '%s %s' % (self.device.id_dict['MFG'], self.device.id_dict['MDL'])
  4019.             except:
  4020.                 nonfatalException()
  4021.  
  4022.             
  4023.             try:
  4024.                 if name == None and isinstance(self.ppd, cups.PPD):
  4025.                     mname = self.ppd.findAttr('modelName').value
  4026.                     (make, model) = cupshelpers.ppds.ppdMakeModelSplit(mname)
  4027.                     name = '%s %s' % (make, model)
  4028.                     descr = '%s %s' % (make, model)
  4029.             except:
  4030.                 nonfatalException()
  4031.  
  4032.             if name == None:
  4033.                 name = 'printer'
  4034.             
  4035.             name = self.mainapp.makeNameUnique(name)
  4036.             self.entNPName.set_text(name)
  4037.             if self.entNPDescription.get_text() == '' and descr:
  4038.                 self.entNPDescription.set_text(descr)
  4039.             
  4040.         
  4041.         self.ntbkNewPrinter.set_current_page(next_page_nr)
  4042.         self.setNPButtons()
  4043.  
  4044.     
  4045.     def setNPButtons(self):
  4046.         nr = self.ntbkNewPrinter.get_current_page()
  4047.         if self.dialog_mode == 'device':
  4048.             self.btnNPBack.hide()
  4049.             self.btnNPForward.hide()
  4050.             self.btnNPApply.show()
  4051.             
  4052.             try:
  4053.                 uri = self.getDeviceURI()
  4054.                 valid = validDeviceURI(uri)
  4055.             except AttributeError:
  4056.                 valid = False
  4057.  
  4058.             self.btnNPApply.set_sensitive(valid)
  4059.             return None
  4060.         self.btnNPForward.show()
  4061.         self.btnNPApply.hide()
  4062.         if nr == 2:
  4063.             downloadable_selected = False
  4064.             if self.rbtnNPDownloadableDriverSearch.get_active():
  4065.                 combobox = self.cmbNPDownloadableDriverFoundPrinters
  4066.                 iter = combobox.get_active_iter()
  4067.                 if iter and combobox.get_model().get_value(iter, 1):
  4068.                     downloadable_selected = True
  4069.                 
  4070.             
  4071.             if not self.rbtnNPFoomatic.get_active() and self.filechooserPPD.get_filename():
  4072.                 pass
  4073.             self.btnNPForward.set_sensitive(bool(downloadable_selected))
  4074.             if self.dialog_mode == 'printer_with_uri':
  4075.                 self.btnNPBack.hide()
  4076.             
  4077.         
  4078.         if nr == 3:
  4079.             (model, iter) = self.tvNPDrivers.get_selection().get_selected()
  4080.             self.btnNPForward.set_sensitive(bool(iter))
  4081.         
  4082.         if nr == 4:
  4083.             self.btnNPForward.hide()
  4084.             self.btnNPApply.show()
  4085.             self.btnNPApply.set_sensitive(bool(getCurrentClassMembers(self.tvNCMembers)))
  4086.         
  4087.         if nr == 6:
  4088.             if self.dialog_mode == 'printer_with_uri' and self.exactdrivermatch:
  4089.                 self.btnNPBack.hide()
  4090.             
  4091.         
  4092.         if nr == 7:
  4093.             if self.ntbkNPDownloadableDriverProperties.get_current_page() == 1:
  4094.                 accepted = self.rbtnNPDownloadLicenseYes.get_active()
  4095.             else:
  4096.                 treeview = self.tvNPDownloadableDrivers
  4097.                 (model, iter) = treeview.get_selection().get_selected()
  4098.                 accepted = iter != None
  4099.             self.btnNPForward.set_sensitive(accepted)
  4100.         
  4101.  
  4102.     
  4103.     def on_entNPName_changed(self, widget):
  4104.         text = unicode(widget.get_text())
  4105.         new_text = text
  4106.         new_text = new_text.replace('/', '')
  4107.         new_text = new_text.replace('#', '')
  4108.         new_text = new_text.replace(' ', '')
  4109.         if text != new_text:
  4110.             widget.set_text(new_text)
  4111.         
  4112.         if self.dialog_mode == 'printer':
  4113.             self.btnNPApply.set_sensitive(self.mainapp.checkNPName(new_text))
  4114.         else:
  4115.             self.btnNPForward.set_sensitive(self.mainapp.checkNPName(new_text))
  4116.  
  4117.     
  4118.     def fetchDevices(self, parent = None):
  4119.         debugprint('fetchDevices')
  4120.         self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for printers'))
  4121.         if parent == None:
  4122.             parent = self.mainapp.PrintersWindow
  4123.         
  4124.         self.WaitWindow.set_transient_for(parent)
  4125.         self.WaitWindow.show_now()
  4126.         while gtk.events_pending():
  4127.             gtk.main_iteration()
  4128.         debugprint('Fetching devices')
  4129.         self.mainapp.cups._begin_operation(_('fetching device list'))
  4130.         
  4131.         try:
  4132.             devices = cupshelpers.getDevices(self.mainapp.cups)
  4133.         except:
  4134.             self.mainapp.cups._end_operation()
  4135.             self.WaitWindow.hide()
  4136.             raise 
  4137.  
  4138.         self.mainapp.cups._end_operation()
  4139.         self.WaitWindow.hide()
  4140.         debugprint('Got devices')
  4141.         return devices
  4142.  
  4143.     
  4144.     def install_hplip_plugin(self, uri):
  4145.         '''
  4146.         Attempt to install a plugin using hp-plugin.
  4147.  
  4148.         @return: True if plugin not needed (or needed and installed),
  4149.         False on error.
  4150.         '''
  4151.         if not self.HP_PLUGIN_SUPPORT:
  4152.             return True
  4153.         os.environ['URI'] = uri
  4154.         cmd = 'LC_ALL=C DISPLAY= hp-info -d"${URI}"'
  4155.         debugprint(uri + ': ' + cmd)
  4156.         
  4157.         try:
  4158.             p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4159.             (stdout, stderr) = p.communicate()
  4160.         except:
  4161.             self.HP_PLUGIN_SUPPORT
  4162.             return True
  4163.  
  4164.         plugin_needed = -1
  4165.         plugin_reason = -1
  4166.         fw_download = -1
  4167.         hplip_version = None
  4168.         for line in stdout.split('\n'):
  4169.             if line.find('plugin ') >= 0:
  4170.                 res = re.search('(\\d+)', line)
  4171.                 if res:
  4172.                     resg = res.groups()
  4173.                     plugin_needed = int(resg[0])
  4174.                 
  4175.             elif line.find('plugin-reason') >= 0:
  4176.                 res = re.search('(\\d+)', line)
  4177.                 if res:
  4178.                     resg = res.groups()
  4179.                     plugin_reason = int(resg[0])
  4180.                 
  4181.             elif line.find('fw-download') >= 0:
  4182.                 if line.find('True') >= 0:
  4183.                     fw_download = 1
  4184.                 elif line.find('False') >= 0:
  4185.                     fw_download = 0
  4186.                 
  4187.             elif line.find('HP Linux Imaging and Printing') >= 0:
  4188.                 res = re.search('(\\d+\\.\\d+\\.\\d+\\w*)', line)
  4189.                 if res:
  4190.                     resg = res.groups()
  4191.                     hplip_version = resg[0]
  4192.                 
  4193.             
  4194.             if plugin_needed >= 0 and plugin_reason >= 0 and fw_download >= 0:
  4195.                 break
  4196.                 continue
  4197.         
  4198.         if plugin_needed <= 0 or not hplip_version:
  4199.             return True
  4200.         if glob.glob('/usr/share/hplip/data/plugin/*%s*plugin*' % hplip_version):
  4201.             if hplip_version.startswith('2'):
  4202.                 
  4203.                 try:
  4204.                     f = open('/etc/hp/hplip.conf', 'r')
  4205.                     for line in f:
  4206.                         if line.strip().startswith('plugin') and line.strip().endswith('1'):
  4207.                             f.close()
  4208.                             return True
  4209.                         f.close()
  4210.  
  4211.             else:
  4212.                 return True
  4213.         hplip_version.startswith('2')
  4214.         text = _('For this printer a proprietary driver plugin from HP is available.\n')
  4215.         if plugin_needed == 1:
  4216.             text += _('The installation of the plugin is required for your printer to work.\n\n')
  4217.         elif plugin_needed == 2:
  4218.             text += _('Installing the plugin is optional, it completes or enhances the functionality\nof your printer. Without plugin at least basic operations work.\n\n')
  4219.         
  4220.         if plugin_reason > 0:
  4221.             text += _('The plugin provides the following features:\n')
  4222.             if plugin_reason & 1 != 0:
  4223.                 text += _(' - Printing support\n')
  4224.             
  4225.             if plugin_reason & 2 != 0:
  4226.                 text += _(' - Faster printing\n')
  4227.             
  4228.             if plugin_reason & 4 != 0:
  4229.                 text += _(' - Better printout quality\n')
  4230.             
  4231.             if plugin_reason & 8 != 0:
  4232.                 text += _(' - Extra printing features\n')
  4233.             
  4234.             if plugin_reason & 64 != 0:
  4235.                 text += _(' - Scanning support\n')
  4236.             
  4237.             if plugin_reason & 128 != 0:
  4238.                 text += _(' - Faster scanning\n')
  4239.             
  4240.             if plugin_reason & 256 != 0:
  4241.                 text += _(' - Better scanning image quality\n')
  4242.             
  4243.             if plugin_reason & 2048 != 0:
  4244.                 text += _(' - Faxing support\n')
  4245.             
  4246.             if plugin_reason & 4096 != 0:
  4247.                 text += _(' - Extra fax features\n')
  4248.             
  4249.             if plugin_reason & 16384 != 0:
  4250.                 text += _(' - Better Input/Output support\n')
  4251.             
  4252.             if plugin_reason & 32768 != 0:
  4253.                 text += _(' - Extra user interface features\n')
  4254.             
  4255.             if plugin_reason & 65536 != 0:
  4256.                 text += _(' - Other extra features\n')
  4257.             
  4258.             text += '\n'
  4259.         
  4260.         text += 'Do you want to download and install the plugin now?\n'
  4261.         if plugin_needed == 1:
  4262.             text += '\nNOTE: The plugin is required for your printer. If you do not install it, your\nprinter will not work.'
  4263.             buttons = (_('Install plugin'), 1, _('Do not set up printer'), 2, _('Set up without plugin'), 3)
  4264.         else:
  4265.             buttons = (_('Yes'), 1, _('No'), 3)
  4266.         dialog = gtk.Dialog(self.device.info, self.NewPrinterWindow, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons)
  4267.         label = gtk.Label(text)
  4268.         dialog.vbox.pack_start(label, True, True, 0)
  4269.         label.show()
  4270.         button_clicked = dialog.run()
  4271.         dialog.destroy()
  4272.         if button_clicked == 1:
  4273.             cmds = ("if python -c 'import PyQt4.QtGui' 2>/dev/null; then gksu -- hp-plugin -u; else exit 255; fi", "gksu -- xterm -T 'HPLIP Plugin Installation' -sb -rightbar -e hp-plugin -i")
  4274.             
  4275.             try:
  4276.                 install_result = -1
  4277.                 for cmd in cmds:
  4278.                     p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4279.                     (stdout, stderr) = p.communicate()
  4280.                     while p.returncode == None:
  4281.                         while gtk.events_pending():
  4282.                             gtk.main_iteration()
  4283.                         time.sleep(0.1)
  4284.                         p.poll()
  4285.                     install_result = p.returncode
  4286.                     if install_result != 255:
  4287.                         break
  4288.                         continue
  4289.                 
  4290.                 if install_result == 0:
  4291.                     return True
  4292.                 return False
  4293.             except OSError:
  4294.                 e = None
  4295.                 debugprint('Execution of hp-plugin failed: %s' % e)
  4296.                 return False
  4297.             
  4298.  
  4299.         None<EXCEPTION MATCH>OSError
  4300.         if button_clicked == 2:
  4301.             return False
  4302.         if button_clicked == 3:
  4303.             return True
  4304.         return False
  4305.  
  4306.     
  4307.     def get_hpfax_device_id(self, faxuri):
  4308.         os.environ['URI'] = faxuri
  4309.         cmd = 'LC_ALL=C DISPLAY= hp-info -d"${URI}"'
  4310.         debugprint(faxuri + ': ' + cmd)
  4311.         
  4312.         try:
  4313.             p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4314.             (stdout, stderr) = p.communicate()
  4315.         except:
  4316.             return None
  4317.  
  4318.         faxtype = -1
  4319.         for line in stdout.split('\n'):
  4320.             if line.find('fax-type') == -1:
  4321.                 continue
  4322.             
  4323.             res = re.search('(\\d+)', line)
  4324.             if res:
  4325.                 resg = res.groups()
  4326.                 faxtype = resg[0]
  4327.             
  4328.             if faxtype >= 0:
  4329.                 break
  4330.                 continue
  4331.         
  4332.         if faxtype <= 0:
  4333.             return None
  4334.         if faxtype == 4:
  4335.             return 'MFG:HP;MDL:Fax 2;DES:HP Fax 2;'
  4336.         return 'MFG:HP;MDL:Fax;DES:HP Fax;'
  4337.  
  4338.     
  4339.     def get_hplip_uri_for_network_printer(self, host, mode):
  4340.         os.environ['HOST'] = host
  4341.         if mode == 'print':
  4342.             mod = '-c'
  4343.         elif mode == 'fax':
  4344.             mod = '-f'
  4345.         else:
  4346.             mod = '-c'
  4347.         cmd = 'hp-makeuri ' + mod + ' "${HOST}"'
  4348.         debugprint(host + ': ' + cmd)
  4349.         uri = None
  4350.         
  4351.         try:
  4352.             p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4353.             (stdout, stderr) = p.communicate()
  4354.         except:
  4355.             return None
  4356.  
  4357.         uri = stdout.strip()
  4358.         return uri
  4359.  
  4360.     
  4361.     def getNetworkPrinterMakeModel(self, host = None, device = None):
  4362.         '''
  4363.         Try to determine the make and model for the currently selected
  4364.         network printer, and store this in the data structure for the
  4365.         printer.
  4366.         Returns (hostname or None, uri or None).
  4367.         '''
  4368.         uri = None
  4369.         if device == None:
  4370.             device = self.device
  4371.         
  4372.         if host == None:
  4373.             s = device.uri.find('://')
  4374.             if s != -1:
  4375.                 s += 3
  4376.                 e = device.uri[s:].find(':')
  4377.                 if e == -1:
  4378.                     e = device.uri[s:].find('/')
  4379.                 
  4380.                 if e == -1:
  4381.                     e = device.uri[s:].find('?')
  4382.                 
  4383.                 if e == -1:
  4384.                     e = len(device.uri)
  4385.                 
  4386.                 host = device.uri[s:s + e]
  4387.             
  4388.         
  4389.         if host:
  4390.             os.environ['HOST'] = host
  4391.             cmd = '/usr/lib/cups/backend/snmp "${HOST}"'
  4392.             debugprint(host + ': ' + cmd)
  4393.             stdout = None
  4394.             
  4395.             try:
  4396.                 p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4397.                 (stdout, stderr) = p.communicate()
  4398.             except:
  4399.                 pass
  4400.  
  4401.             if stdout != None:
  4402.                 uri = re.sub('^\\s*\\S+\\s+', '', stdout)
  4403.                 uri = re.sub('\\s.*$', '', uri)
  4404.                 mm = re.sub('^\\s*\\S+\\s+\\S+\\s+"', '', stdout)
  4405.                 mm = re.sub('"\\s+.*$', '', mm)
  4406.                 if mm and mm != '':
  4407.                     device.make_and_model = mm
  4408.                 
  4409.             
  4410.         
  4411.         make_and_model = None
  4412.         if len(device.make_and_model) > 7:
  4413.             make_and_model = device.make_and_model
  4414.         elif len(device.info) > 7:
  4415.             make_and_model = device.info
  4416.             make_and_model = re.sub('\\s*(\\(|\\d+\\.\\d+\\.\\d+\\.\\d+).*$', '', make_and_model)
  4417.         
  4418.         if make_and_model and not (device.id):
  4419.             mk = None
  4420.             md = None
  4421.             (mk, md) = cupshelpers.ppds.ppdMakeModelSplit(make_and_model)
  4422.             device.id = 'MFG:' + mk + ';MDL:' + md + ';DES:' + mk + ' ' + md + ';'
  4423.             device.id_dict = cupshelpers.parseDeviceID(device.id)
  4424.         
  4425.         return (host, uri)
  4426.  
  4427.     
  4428.     def fillDeviceTab(self, current_uri = None):
  4429.         
  4430.         try:
  4431.             devices = self.fetchDevices()
  4432.         except cups.IPPError:
  4433.             (e, msg) = None
  4434.             self.show_IPP_Error(e, msg)
  4435.             devices = { }
  4436.         except:
  4437.             nonfatalException()
  4438.             devices = { }
  4439.  
  4440.         if current_uri:
  4441.             if devices.has_key(current_uri):
  4442.                 current = devices.pop(current_uri)
  4443.                 current.info += _(' (Current)')
  4444.             elif devices.has_key(current_uri.replace(':9100', '')):
  4445.                 current_uri = current_uri.replace(':9100', '')
  4446.                 current = devices.pop(current_uri)
  4447.                 current.info += _(' (Current)')
  4448.             else:
  4449.                 current = cupshelpers.Device(current_uri)
  4450.                 current.info = 'Current device'
  4451.         
  4452.         devices = devices.values()
  4453.         for device in devices:
  4454.             if device.type == 'socket':
  4455.                 device.uri = device.uri.replace(':9100', '')
  4456.                 continue
  4457.         
  4458.         
  4459.         def replace_generic(device):
  4460.             if device.uri == 'hp:/no_device_found':
  4461.                 device.uri = 'hp'
  4462.             elif device.uri == 'hpfax:/no_device_found':
  4463.                 device.uri = 'hpfax'
  4464.             
  4465.             return device
  4466.  
  4467.         devices = map(replace_generic, devices)
  4468.         for each in devices:
  4469.             if each.type == 'hp':
  4470.                 if each.uri != 'hp':
  4471.                     hp = cupshelpers.Device('hp', **{
  4472.                         'device-class': 'network',
  4473.                         'device-info': _('HP Printer (HPLIP)') })
  4474.                     devices.append(hp)
  4475.                     break
  4476.                 else:
  4477.                     each.device_class = 'network'
  4478.             each.uri != 'hp'
  4479.         
  4480.         for i in range(len(devices) - 1):
  4481.             for j in range(i + 1, len(devices)):
  4482.                 device1 = devices[i]
  4483.                 device2 = devices[j]
  4484.                 if device1.uri == 'delete' or device2.uri == 'delete':
  4485.                     continue
  4486.                 
  4487.                 if device1.uri == device2.uri:
  4488.                     if not device1.id:
  4489.                         device1.uri = 'delete'
  4490.                     elif not device2.id:
  4491.                         device2.uri = 'delete'
  4492.                     elif len(device1.id) < len(device2.id):
  4493.                         device1.uri = 'delete'
  4494.                     else:
  4495.                         device2.uri = 'delete'
  4496.                 device1.id
  4497.             
  4498.         
  4499.         devices = filter((lambda x: x.uri not in ('hpfax', 'hal', 'beh', 'scsi', 'http', 'delete')), devices)
  4500.         self.devices = []
  4501.         for device in devices:
  4502.             physicaldevice = PhysicalDevice(device)
  4503.             
  4504.             try:
  4505.                 i = self.devices.index(physicaldevice)
  4506.                 self.devices[i].add_device(device)
  4507.             continue
  4508.             except ValueError:
  4509.                 self.devices.append(physicaldevice)
  4510.                 continue
  4511.             
  4512.  
  4513.         
  4514.         self.devices.sort()
  4515.         other = cupshelpers.Device('', **{
  4516.             'device-info': _('Other') })
  4517.         self.devices.append(PhysicalDevice(other))
  4518.         device_select_index = 0
  4519.         if current_uri:
  4520.             current_device = PhysicalDevice(current)
  4521.             
  4522.             try:
  4523.                 i = self.devices.index(current_device)
  4524.                 self.devices[i].add_device(current)
  4525.                 device_select_index = i
  4526.                 devs = self.devices[i].get_devices()
  4527.             except ValueError:
  4528.                 None<EXCEPTION MATCH>ValueError
  4529.                 None<EXCEPTION MATCH>ValueError
  4530.                 self.devices.insert(0, current_device)
  4531.             except:
  4532.                 None<EXCEPTION MATCH>ValueError<EXCEPTION MATCH>ValueError
  4533.             
  4534.  
  4535.         None<EXCEPTION MATCH>ValueError
  4536.         model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)
  4537.         network_iter = model.append(None, row = [
  4538.             _('Network Printer'),
  4539.             None,
  4540.             False])
  4541.         network_dict = {
  4542.             'device-class': 'network',
  4543.             'device-info': _('Find Network Printer') }
  4544.         network = cupshelpers.Device('network', **network_dict)
  4545.         find_nw_iter = model.append(network_iter, row = [
  4546.             network_dict['device-info'],
  4547.             PhysicalDevice(network),
  4548.             False])
  4549.         model.insert_after(network_iter, find_nw_iter, row = [
  4550.             '',
  4551.             None,
  4552.             True])
  4553.         self.devices_find_nw_iter = find_nw_iter
  4554.         self.tvNPDevices.set_model(model)
  4555.         i = 0
  4556.         device_select_path = None
  4557.         for device in self.devices:
  4558.             devs = device.get_devices()
  4559.             network = devs[0].device_class == 'network'
  4560.             row = [
  4561.                 device.get_info(),
  4562.                 device,
  4563.                 False]
  4564.             if network:
  4565.                 if devs[0].uri != devs[0].type:
  4566.                     iter = model.insert_before(network_iter, find_nw_iter, row = row)
  4567.                     if device_select_index == i:
  4568.                         network_path = model.get_path(network_iter)
  4569.                         self.tvNPDevices.expand_row(network_path, False)
  4570.                     
  4571.                 else:
  4572.                     iter = model.append(network_iter, row = row)
  4573.             else:
  4574.                 iter = model.insert_before(None, network_iter, row = row)
  4575.             if device_select_index == i:
  4576.                 device_select_path = model.get_path(iter)
  4577.                 self.tvNPDevices.scroll_to_cell(device_select_path, row_align = 0.5)
  4578.                 column = self.tvNPDevices.get_column(0)
  4579.                 self.tvNPDevices.set_cursor(device_select_path, column)
  4580.             
  4581.             i += 1
  4582.         
  4583.         connection_select_path = 0
  4584.         if current_uri:
  4585.             model = self.tvNPDeviceURIs.get_model()
  4586.             iter = model.get_iter_first()
  4587.             i = 0
  4588.             while iter:
  4589.                 dev = model.get_value(iter, 1)
  4590.                 if current_uri == dev.uri:
  4591.                     connection_select_path = i
  4592.                     break
  4593.                 
  4594.                 iter = model.iter_next(iter)
  4595.                 i += 1
  4596.         
  4597.         column = self.tvNPDeviceURIs.get_column(0)
  4598.         self.tvNPDeviceURIs.set_cursor(connection_select_path, column)
  4599.  
  4600.     
  4601.     def on_entNPTDevice_changed(self, entry):
  4602.         self.setNPButtons()
  4603.  
  4604.     
  4605.     def browse_smb_hosts(self):
  4606.         '''Initialise the SMB tree store.'''
  4607.         store = self.smb_store
  4608.         store.clear()
  4609.         self.busy(self.SMBBrowseDialog)
  4610.         
  4611.         class X:
  4612.             pass
  4613.  
  4614.         dummy = X()
  4615.         dummy.smbc_type = pysmb.smbc.PRINTER_SHARE
  4616.         dummy.name = _('Scanning...')
  4617.         dummy.comment = ''
  4618.         store.append(None, [
  4619.             dummy])
  4620.         while gtk.events_pending():
  4621.             gtk.main_iteration()
  4622.         debug = 0
  4623.         if get_debugging():
  4624.             debug = 10
  4625.         
  4626.         smbc_auth = pysmb.AuthContext(self.SMBBrowseDialog)
  4627.         ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  4628.         entries = None
  4629.         
  4630.         try:
  4631.             while smbc_auth.perform_authentication() > 0:
  4632.                 
  4633.                 try:
  4634.                     entries = ctx.opendir('smb://').getdents()
  4635.                 continue
  4636.                 except Exception:
  4637.                     e = None
  4638.                     smbc_auth.failed(e)
  4639.                     continue
  4640.                 
  4641.  
  4642.                 None<EXCEPTION MATCH>Exception
  4643.         except RuntimeError:
  4644.             (e, s) = None
  4645.             if e != errno.ENOENT:
  4646.                 debugprint('Runtime error: %s' % repr((e, s)))
  4647.             
  4648.         except:
  4649.             e != errno.ENOENT
  4650.             nonfatalException()
  4651.  
  4652.         store.clear()
  4653.         if entries:
  4654.             for entry in entries:
  4655.                 if entry.smbc_type in [
  4656.                     pysmb.smbc.WORKGROUP,
  4657.                     pysmb.smbc.SERVER]:
  4658.                     iter = store.append(None, [
  4659.                         entry])
  4660.                     i = store.append(iter)
  4661.                     continue
  4662.             
  4663.         
  4664.         specified_uri = SMBURI(uri = self.entSMBURI.get_text())
  4665.         (group, host, share, user, password) = specified_uri.separate()
  4666.         if len(host) > 0:
  4667.             
  4668.             class FakeEntry:
  4669.                 pass
  4670.  
  4671.             toplevel = FakeEntry()
  4672.             toplevel.smbc_type = pysmb.smbc.SERVER
  4673.             toplevel.name = host
  4674.             toplevel.comment = ''
  4675.             iter = store.append(None, [
  4676.                 toplevel])
  4677.             i = store.append(iter)
  4678.             path = store.get_path(iter)
  4679.             self.tvSMBBrowser.expand_row(path, 0)
  4680.         
  4681.         self.ready(self.SMBBrowseDialog)
  4682.         if store.get_iter_first() == None:
  4683.             self.SMBBrowseDialog.hide()
  4684.             show_info_dialog(_('No Print Shares'), _('There were no print shares found.  Please check that the Samba service is marked as trusted in your firewall configuration.') + '\n\n' + TEXT_start_firewall_tool, parent = self.NewPrinterWindow)
  4685.         
  4686.  
  4687.     
  4688.     def smb_select_function(self, path):
  4689.         """Don't allow this path to be selected unless it is a leaf."""
  4690.         iter = self.smb_store.get_iter(path)
  4691.         return not self.smb_store.iter_has_child(iter)
  4692.  
  4693.     
  4694.     def smbbrowser_cell_share(self, column, cell, model, iter):
  4695.         entry = model.get_value(iter, 0)
  4696.         share = ''
  4697.         if entry != None:
  4698.             share = entry.name
  4699.         
  4700.         cell.set_property('text', share)
  4701.  
  4702.     
  4703.     def smbbrowser_cell_comment(self, column, cell, model, iter):
  4704.         entry = model.get_value(iter, 0)
  4705.         comment = ''
  4706.         if entry != None:
  4707.             comment = entry.comment
  4708.         
  4709.         cell.set_property('text', comment)
  4710.  
  4711.     
  4712.     def on_tvSMBBrowser_row_activated(self, view, path, column):
  4713.         '''Handle double-clicks in the SMB tree view.'''
  4714.         store = self.smb_store
  4715.         iter = store.get_iter(path)
  4716.         entry = store.get_value(iter, 0)
  4717.         if entry and entry.smbc_type == pysmb.smbc.PRINTER_SHARE:
  4718.             self.btnSMBBrowseOk.clicked()
  4719.             return None
  4720.         if view.row_expanded(path):
  4721.             view.collapse_row(path)
  4722.         else:
  4723.             self.on_tvSMBBrowser_row_expanded(view, iter, path)
  4724.  
  4725.     
  4726.     def on_tvSMBBrowser_row_expanded(self, view, iter, path):
  4727.         '''Handler for expanding a row in the SMB tree view.'''
  4728.         model = view.get_model()
  4729.         entry = model.get_value(iter, 0)
  4730.         if entry == None:
  4731.             return None
  4732.         if entry.smbc_type == pysmb.smbc.WORKGROUP:
  4733.             
  4734.             try:
  4735.                 if self.expanding_row:
  4736.                     return None
  4737.             except:
  4738.                 entry == None
  4739.                 self.expanding_row = 1
  4740.  
  4741.             self.busy(self.SMBBrowseDialog)
  4742.             uri = 'smb://%s/' % entry.name
  4743.             debug = 0
  4744.             if get_debugging():
  4745.                 debug = 10
  4746.             
  4747.             smbc_auth = pysmb.AuthContext(self.SMBBrowseDialog)
  4748.             ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  4749.             entries = []
  4750.             
  4751.             try:
  4752.                 while smbc_auth.perform_authentication() > 0:
  4753.                     
  4754.                     try:
  4755.                         entries = ctx.opendir(uri).getdents()
  4756.                     continue
  4757.                     except Exception:
  4758.                         e = None
  4759.                         smbc_auth.failed(e)
  4760.                         continue
  4761.                     
  4762.  
  4763.                     None<EXCEPTION MATCH>Exception
  4764.             except RuntimeError:
  4765.                 (e, s) = None
  4766.                 if e != errno.ENOENT:
  4767.                     debugprint('Runtime error: %s' % repr((e, s)))
  4768.                 
  4769.             except:
  4770.                 e != errno.ENOENT
  4771.                 nonfatalException()
  4772.  
  4773.             while model.iter_has_child(iter):
  4774.                 i = model.iter_nth_child(iter, 0)
  4775.                 model.remove(i)
  4776.             for entry in entries:
  4777.                 if entry.smbc_type in [
  4778.                     pysmb.smbc.SERVER,
  4779.                     pysmb.smbc.PRINTER_SHARE]:
  4780.                     i = model.append(iter, [
  4781.                         entry])
  4782.                 
  4783.                 if entry.smbc_type == pysmb.smbc.SERVER:
  4784.                     n = model.append(i)
  4785.                     continue
  4786.             
  4787.             view.expand_row(path, 0)
  4788.             del self.expanding_row
  4789.             self.ready(self.SMBBrowseDialog)
  4790.         elif entry.smbc_type == pysmb.smbc.SERVER:
  4791.             
  4792.             try:
  4793.                 if self.expanding_row:
  4794.                     return None
  4795.             except:
  4796.                 entry == None
  4797.                 self.expanding_row = 1
  4798.  
  4799.             self.busy(self.SMBBrowseDialog)
  4800.             uri = 'smb://%s/' % entry.name
  4801.             debug = 0
  4802.             if get_debugging():
  4803.                 debug = 10
  4804.             
  4805.             smbc_auth = pysmb.AuthContext(self.SMBBrowseDialog)
  4806.             ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  4807.             shares = []
  4808.             
  4809.             try:
  4810.                 while smbc_auth.perform_authentication() > 0:
  4811.                     
  4812.                     try:
  4813.                         shares = ctx.opendir(uri).getdents()
  4814.                     continue
  4815.                     except Exception:
  4816.                         e = None
  4817.                         smbc_auth.failed(e)
  4818.                         continue
  4819.                     
  4820.  
  4821.                     None<EXCEPTION MATCH>Exception
  4822.             except RuntimeError:
  4823.                 (e, s) = None
  4824.                 if e != errno.EACCES and e != errno.EPERM:
  4825.                     debugprint('Runtime error: %s' % repr((e, s)))
  4826.                 
  4827.             except:
  4828.                 e != errno.EPERM
  4829.                 nonfatalException()
  4830.  
  4831.             while model.iter_has_child(iter):
  4832.                 i = model.iter_nth_child(iter, 0)
  4833.                 model.remove(i)
  4834.             for share in shares:
  4835.                 if share.smbc_type == pysmb.smbc.PRINTER_SHARE:
  4836.                     i = model.append(iter, [
  4837.                         share])
  4838.                     debugprint(repr(share))
  4839.                     continue
  4840.             
  4841.             view.expand_row(path, 0)
  4842.             del self.expanding_row
  4843.             self.ready(self.SMBBrowseDialog)
  4844.         
  4845.  
  4846.     
  4847.     def on_entSMBURI_changed(self, ent):
  4848.         uri = ent.get_text()
  4849.         (group, host, share, user, password) = SMBURI(uri = uri).separate()
  4850.         if user:
  4851.             self.entSMBUsername.set_text(user)
  4852.         
  4853.         if password:
  4854.             self.entSMBPassword.set_text(password)
  4855.         
  4856.         if user or password:
  4857.             uri = SMBURI(group = group, host = host, share = share).get_uri()
  4858.             ent.set_text(uri)
  4859.             self.rbtnSMBAuthSet.set_active(True)
  4860.         elif self.entSMBUsername.get_text() == '':
  4861.             self.rbtnSMBAuthPrompt.set_active(True)
  4862.         
  4863.         self.btnSMBVerify.set_sensitive(bool(uri))
  4864.         self.setNPButtons()
  4865.  
  4866.     
  4867.     def on_tvSMBBrowser_cursor_changed(self, widget):
  4868.         (store, iter) = self.tvSMBBrowser.get_selection().get_selected()
  4869.         is_share = False
  4870.         if iter:
  4871.             entry = store.get_value(iter, 0)
  4872.             if entry:
  4873.                 is_share = entry.smbc_type == pysmb.smbc.PRINTER_SHARE
  4874.             
  4875.         
  4876.         if iter != None:
  4877.             pass
  4878.         self.btnSMBBrowseOk.set_sensitive(is_share)
  4879.  
  4880.     
  4881.     def on_btnSMBBrowse_clicked(self, button):
  4882.         self.btnSMBBrowseOk.set_sensitive(False)
  4883.         self.SMBBrowseDialog.show()
  4884.         self.browse_smb_hosts()
  4885.  
  4886.     
  4887.     def on_btnSMBBrowseOk_clicked(self, button):
  4888.         (store, iter) = self.tvSMBBrowser.get_selection().get_selected()
  4889.         is_share = False
  4890.         if iter:
  4891.             entry = store.get_value(iter, 0)
  4892.             if entry:
  4893.                 is_share = entry.smbc_type == pysmb.smbc.PRINTER_SHARE
  4894.             
  4895.         
  4896.         if not iter or not is_share:
  4897.             self.SMBBrowseDialog.hide()
  4898.             return None
  4899.         parent_iter = store.iter_parent(iter)
  4900.         domain_iter = store.iter_parent(parent_iter)
  4901.         share = store.get_value(iter, 0)
  4902.         host = store.get_value(parent_iter, 0)
  4903.         if domain_iter:
  4904.             group = store.get_value(domain_iter, 0).name
  4905.         else:
  4906.             group = ''
  4907.         uri = SMBURI(group = group, host = host.name, share = share.name).get_uri()
  4908.         self.entSMBUsername.set_text('')
  4909.         self.entSMBPassword.set_text('')
  4910.         self.entSMBURI.set_text(uri)
  4911.         self.SMBBrowseDialog.hide()
  4912.  
  4913.     
  4914.     def on_btnSMBBrowseCancel_clicked(self, widget, *args):
  4915.         self.SMBBrowseDialog.hide()
  4916.  
  4917.     
  4918.     def on_btnSMBBrowseRefresh_clicked(self, button):
  4919.         self.browse_smb_hosts()
  4920.  
  4921.     
  4922.     def on_rbtnSMBAuthSet_toggled(self, widget):
  4923.         self.tblSMBAuth.set_sensitive(widget.get_active())
  4924.  
  4925.     
  4926.     def on_btnSMBVerify_clicked(self, button):
  4927.         uri = self.entSMBURI.get_text()
  4928.         (group, host, share, u, p) = SMBURI(uri = uri).separate()
  4929.         user = ''
  4930.         passwd = ''
  4931.         reason = None
  4932.         auth_set = self.rbtnSMBAuthSet.get_active()
  4933.         if auth_set:
  4934.             user = self.entSMBUsername.get_text()
  4935.             passwd = self.entSMBPassword.get_text()
  4936.         
  4937.         accessible = False
  4938.         canceled = False
  4939.         self.busy()
  4940.         
  4941.         try:
  4942.             debug = 0
  4943.             if get_debugging():
  4944.                 debug = 10
  4945.             
  4946.             if auth_set:
  4947.                 
  4948.                 def do_auth(svr, shr, wg, un, pw):
  4949.                     return (group, user, passwd)
  4950.  
  4951.                 ctx = pysmb.smbc.Context(debug = debug, auth_fn = do_auth)
  4952.                 f = ctx.open('smb://%s/%s' % (host, share), os.O_RDWR, 511)
  4953.                 accessible = True
  4954.             else:
  4955.                 smbc_auth = pysmb.AuthContext(self.NewPrinterWindow, workgroup = group, user = user, passwd = passwd)
  4956.                 ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  4957.                 while smbc_auth.perform_authentication() > 0:
  4958.                     
  4959.                     try:
  4960.                         f = ctx.open('smb://%s/%s' % (host, share), os.O_RDWR, 511)
  4961.                         accessible = True
  4962.                     continue
  4963.                     except Exception:
  4964.                         e = None
  4965.                         smbc_auth.failed(e)
  4966.                         continue
  4967.                     
  4968.  
  4969.                     None<EXCEPTION MATCH>Exception
  4970.                 if not accessible:
  4971.                     canceled = True
  4972.         except RuntimeError:
  4973.             (e, s) = None
  4974.             debugprint('Error accessing share: %s' % repr((e, s)))
  4975.             reason = s
  4976.         except:
  4977.             nonfatalException()
  4978.         
  4979.  
  4980.         self.ready()
  4981.         if accessible:
  4982.             show_info_dialog(_('Print Share Verified'), _('This print share is accessible.'), parent = self.NewPrinterWindow)
  4983.             return None
  4984.  
  4985.     
  4986.     def update_IPP_URI_label(self):
  4987.         hostname = self.entNPTIPPHostname.get_text()
  4988.         queue = self.entNPTIPPQueuename.get_text()
  4989.         if len(hostname) > 0:
  4990.             pass
  4991.         valid = queue != '/printers/'
  4992.         if valid:
  4993.             uri = 'ipp://%s%s' % (hostname, queue)
  4994.             self.lblIPPURI.set_text(uri)
  4995.             self.lblIPPURI.show()
  4996.             self.entNPTIPPQueuename.show()
  4997.         else:
  4998.             self.lblIPPURI.hide()
  4999.         self.btnIPPVerify.set_sensitive(valid)
  5000.         self.setNPButtons()
  5001.  
  5002.     
  5003.     def on_entNPTIPPHostname_changed(self, ent):
  5004.         valid = len(ent.get_text()) > 0
  5005.         self.btnIPPFindQueue.set_sensitive(valid)
  5006.         self.update_IPP_URI_label()
  5007.  
  5008.     
  5009.     def on_entNPTIPPQueuename_changed(self, ent):
  5010.         self.update_IPP_URI_label()
  5011.  
  5012.     
  5013.     def on_btnIPPFindQueue_clicked(self, button):
  5014.         self.btnIPPBrowseOk.set_sensitive(False)
  5015.         self.IPPBrowseDialog.show()
  5016.         self.browse_ipp_queues()
  5017.  
  5018.     
  5019.     def on_btnIPPVerify_clicked(self, button):
  5020.         uri = self.lblIPPURI.get_text()
  5021.         match = re.match('(ipp|https?)://([^/]+)(.*)/([^/]*)', uri)
  5022.         verified = False
  5023.         if match:
  5024.             oldserver = cups.getServer()
  5025.             
  5026.             try:
  5027.                 c = cups.Connection(host = match.group(2))
  5028.                 attributes = c.getPrinterAttributes(uri = uri)
  5029.                 verified = True
  5030.             except cups.IPPError:
  5031.                 (e, msg) = None
  5032.                 debugprint('Failed to get attributes: %s (%d)' % (msg, e))
  5033.             except:
  5034.                 nonfatalException()
  5035.  
  5036.             cups.setServer(oldserver)
  5037.         else:
  5038.             debugprint(uri)
  5039.         if verified:
  5040.             show_info_dialog(_('Print Share Verified'), _('This print share is accessible.'), parent = self.NewPrinterWindow)
  5041.         else:
  5042.             show_error_dialog(_('Inaccessible'), _('This print share is not accessible.'), self.NewPrinterWindow)
  5043.  
  5044.     
  5045.     def browse_ipp_queues(self):
  5046.         if not self.ipp_lock.acquire(0):
  5047.             return None
  5048.         thread.start_new_thread(self.browse_ipp_queues_thread, ())
  5049.  
  5050.     
  5051.     def browse_ipp_queues_thread(self):
  5052.         host = None
  5053.         gtk.gdk.threads_enter()
  5054.         
  5055.         try:
  5056.             store = self.ipp_store
  5057.             store.clear()
  5058.             store.append(None, (_('Scanning...'), '', None))
  5059.             
  5060.             try:
  5061.                 self.busy(self.IPPBrowseDialog)
  5062.             except:
  5063.                 nonfatalException()
  5064.  
  5065.             host = self.entNPTIPPHostname.get_text()
  5066.         except:
  5067.             nonfatalException()
  5068.  
  5069.         gtk.gdk.threads_leave()
  5070.         oldserver = cups.getServer()
  5071.         printers = classes = { }
  5072.         failed = False
  5073.         port = 631
  5074.         if host != None:
  5075.             (host, port) = urllib.splitnport(host, defport = port)
  5076.         
  5077.         
  5078.         try:
  5079.             c = cups.Connection(host = host, port = port)
  5080.             printers = c.getPrinters()
  5081.             del c
  5082.         except cups.IPPError:
  5083.             (e, m) = None
  5084.             debugprint('IPP browser: %s' % m)
  5085.             failed = True
  5086.         except:
  5087.             nonfatalException()
  5088.             failed = True
  5089.  
  5090.         cups.setServer(oldserver)
  5091.         gtk.gdk.threads_enter()
  5092.         
  5093.         try:
  5094.             store.clear()
  5095.             for printer, dict in printers.iteritems():
  5096.                 iter = store.append(None)
  5097.                 store.set_value(iter, 0, printer)
  5098.                 store.set_value(iter, 1, dict.get('printer-location', ''))
  5099.                 store.set_value(iter, 2, dict)
  5100.             
  5101.             if len(printers) + len(classes) == 0:
  5102.                 if failed:
  5103.                     title = _('Not possible')
  5104.                     text = _("It is not possible to obtain a list of queues from '%s'.") % host + '\n\n' + _('Obtaining a list of queues is a CUPS extension to IPP.  Network printers do not support it.')
  5105.                 else:
  5106.                     title = _('No queues')
  5107.                     text = _('There are no queues available.')
  5108.                 self.IPPBrowseDialog.hide()
  5109.                 show_error_dialog(title, text, self.NewPrinterWindow)
  5110.             
  5111.             
  5112.             try:
  5113.                 self.ready(self.IPPBrowseDialog)
  5114.             except:
  5115.                 nonfatalException()
  5116.  
  5117.             self.ipp_lock.release()
  5118.         except:
  5119.             nonfatalException()
  5120.  
  5121.         gtk.gdk.threads_leave()
  5122.  
  5123.     
  5124.     def on_tvIPPBrowser_cursor_changed(self, widget):
  5125.         self.btnIPPBrowseOk.set_sensitive(True)
  5126.  
  5127.     
  5128.     def on_btnIPPBrowseOk_clicked(self, button):
  5129.         (store, iter) = self.tvIPPBrowser.get_selection().get_selected()
  5130.         self.IPPBrowseDialog.hide()
  5131.         queue = store.get_value(iter, 0)
  5132.         dict = store.get_value(iter, 2)
  5133.         self.entNPTIPPQueuename.set_text(queue)
  5134.         self.entNPTIPPQueuename.show()
  5135.         uri = dict.get('printer-uri-supported', 'ipp')
  5136.         match = re.match('(ipp|https?)://([^/]+)(.*)', uri)
  5137.         if match:
  5138.             self.entNPTIPPHostname.set_text(match.group(2))
  5139.             self.entNPTIPPQueuename.set_text(match.group(3))
  5140.         
  5141.         self.lblIPPURI.set_text(uri)
  5142.         self.lblIPPURI.show()
  5143.         self.setNPButtons()
  5144.  
  5145.     
  5146.     def on_btnIPPBrowseCancel_clicked(self, widget, *args):
  5147.         self.IPPBrowseDialog.hide()
  5148.  
  5149.     
  5150.     def on_btnIPPBrowseRefresh_clicked(self, button):
  5151.         self.browse_ipp_queues()
  5152.  
  5153.     
  5154.     def on_expNPDeviceURIs_expanded(self, widget, UNUSED):
  5155.         parent = widget.get_parent()
  5156.         (expand, fill, padding, pack_type) = parent.query_child_packing(widget)
  5157.         expand = widget.get_expanded()
  5158.         parent.set_child_packing(widget, expand, fill, padding, pack_type)
  5159.  
  5160.     
  5161.     def device_row_separator_fn(self, model, iter):
  5162.         return model.get_value(iter, 2)
  5163.  
  5164.     
  5165.     def device_row_activated(self, view, path, column):
  5166.         if view.row_expanded(path):
  5167.             view.collapse_row(path)
  5168.         else:
  5169.             view.expand_row(path, False)
  5170.  
  5171.     
  5172.     def device_select_function(self, path):
  5173.         '''
  5174.         Allow this path to be selected as long as there
  5175.         is a device associated with it.
  5176.         '''
  5177.         model = self.tvNPDevices.get_model()
  5178.         iter = model.get_iter(path)
  5179.         return model.get_value(iter, 1) != None
  5180.  
  5181.     
  5182.     def on_tvNPDevices_cursor_changed(self, widget):
  5183.         (path, column) = widget.get_cursor()
  5184.         if path == None:
  5185.             return None
  5186.         model = widget.get_model()
  5187.         iter = model.get_iter(path)
  5188.         physicaldevice = model.get_value(iter, 1)
  5189.         if physicaldevice == None:
  5190.             return None
  5191.         for device in physicaldevice.get_devices():
  5192.             if device.type == 'parallel':
  5193.                 device.menuentry = _('Parallel Port')
  5194.                 continue
  5195.             physicaldevice == None
  5196.             if device.type == 'serial':
  5197.                 device.menuentry = _('Serial Port')
  5198.                 continue
  5199.             path == None
  5200.             if device.type == 'usb':
  5201.                 device.menuentry = _('USB')
  5202.                 continue
  5203.             if device.type == 'hp':
  5204.                 device.menuentry = _('HP Linux Imaging and Printing (HPLIP)')
  5205.                 continue
  5206.             if device.type == 'hpfax':
  5207.                 device.menuentry = _('Fax') + ' - ' + _('HP Linux Imaging and Printing (HPLIP)')
  5208.                 continue
  5209.             if device.type == 'hal':
  5210.                 device.menuentry = _('Hardware Abstraction Layer (HAL)')
  5211.                 continue
  5212.             if device.type == 'socket':
  5213.                 device.menuentry = _('AppSocket/HP JetDirect')
  5214.                 continue
  5215.             if device.type == 'lpd':
  5216.                 device.menuentry = _('LPD/LPR')
  5217.                 continue
  5218.             if device.type == 'smb':
  5219.                 device.menuentry = _('Windows Printer via SAMBA')
  5220.                 continue
  5221.             if device.type == 'ipp':
  5222.                 device.menuentry = _('IPP')
  5223.                 continue
  5224.             if device.type == 'http':
  5225.                 device.menuentry = _('HTTP')
  5226.                 continue
  5227.             device.menuentry = device.uri
  5228.         
  5229.         model = gtk.ListStore(str, gobject.TYPE_PYOBJECT)
  5230.         self.tvNPDeviceURIs.set_model(model)
  5231.         if physicaldevice.get_data('checked-hplip') != True:
  5232.             hp_drivable = False
  5233.             is_network = False
  5234.             device_dict = {
  5235.                 'device-class': 'network' }
  5236.             for device in physicaldevice.get_devices():
  5237.                 if device.type == 'hp':
  5238.                     hp_drivable = True
  5239.                     break
  5240.                     continue
  5241.                 if device.type in ('socket', 'lpd', 'ipp'):
  5242.                     (scheme, rest) = urllib.splittype(device.uri)
  5243.                     (hostport, rest) = urllib.splithost(rest)
  5244.                     if hostport != None:
  5245.                         (host, port) = urllib.splitport(hostport)
  5246.                         is_network = True
  5247.                         self.getNetworkPrinterMakeModel(host = host, device = device)
  5248.                         device_dict['device-info'] = device.info
  5249.                         device_dict['device-make-and-model'] = device.make_and_model
  5250.                         device_dict['device-id'] = device.id
  5251.                     
  5252.                 hostport != None
  5253.             
  5254.             if not hp_drivable and is_network:
  5255.                 hplipuri = self.get_hplip_uri_for_network_printer(host, 'print')
  5256.                 if hplipuri:
  5257.                     dev = cupshelpers.Device(hplipuri, **device_dict)
  5258.                     dev.menuentry = 'HP Linux Imaging and Printing (HPLIP)'
  5259.                     physicaldevice.add_device(dev)
  5260.                     faxuri = self.get_hplip_uri_for_network_printer(host, 'fax')
  5261.                     if faxuri:
  5262.                         faxdevid = self.get_hpfax_device_id(faxuri)
  5263.                         device_dict['device-id'] = faxdevid
  5264.                         device_dict['device-info'] = _('Fax')
  5265.                         faxdev = cupshelpers.Device(faxuri, **device_dict)
  5266.                         faxdev.menuentry = _('Fax') + ' - ' + 'HP Linux Imaging and Printing (HPLIP)'
  5267.                         physicaldevice.add_device(faxdev)
  5268.                     
  5269.                 
  5270.                 physicaldevice.set_data('checked-hplip', True)
  5271.             
  5272.         
  5273.         n = 0
  5274.         for device in physicaldevice.get_devices():
  5275.             model.append((device.menuentry, device))
  5276.             n += 1
  5277.         
  5278.         column = self.tvNPDeviceURIs.get_column(0)
  5279.         self.tvNPDeviceURIs.set_cursor(0, column)
  5280.         if n > 1:
  5281.             self.expNPDeviceURIs.show_all()
  5282.         else:
  5283.             self.expNPDeviceURIs.hide()
  5284.  
  5285.     
  5286.     def on_tvNPDeviceURIs_cursor_changed(self, widget):
  5287.         (model, iter) = widget.get_selection().get_selected()
  5288.         device = model.get_value(iter, 1)
  5289.         self.device = device
  5290.         self.lblNPDeviceDescription.set_text('')
  5291.         page = self.new_printer_device_tabs.get(device.type, 1)
  5292.         if device.type == 'hp' and device.uri != 'hp':
  5293.             page = 0
  5294.         
  5295.         self.ntbkNPType.set_current_page(page)
  5296.         location = ''
  5297.         type = device.type
  5298.         url = device.uri.split(':', 1)[-1]
  5299.         if page == 0:
  5300.             if device.type == 'parallel':
  5301.                 text = _('A printer connected to the parallel port.')
  5302.             elif device.type == 'usb':
  5303.                 text = _('A printer connected to a USB port.')
  5304.             elif device.type == 'hp':
  5305.                 text = _('HPLIP software driving a printer, or the printer function of a multi-function device.')
  5306.             elif device.type == 'hpfax':
  5307.                 text = _('HPLIP software driving a fax machine, or the fax function of a multi-function device.')
  5308.             elif device.type == 'hal':
  5309.                 text = _('Local printer detected by the Hardware Abstraction Layer (HAL).')
  5310.             else:
  5311.                 text = device.uri
  5312.             self.lblNPDeviceDescription.set_text(text)
  5313.         elif device.type == 'socket':
  5314.             (scheme, rest) = urllib.splittype(device.uri)
  5315.             host = ''
  5316.             port = 9100
  5317.             if scheme == 'socket':
  5318.                 (hostport, rest) = urllib.splithost(rest)
  5319.                 (host, port) = urllib.splitnport(hostport, defport = port)
  5320.                 debugprint('socket: host is %s, port is %s' % (host, repr(port)))
  5321.                 location = host
  5322.             
  5323.             self.entNPTDirectJetHostname.set_text(host)
  5324.             self.entNPTDirectJetPort.set_text(str(port))
  5325.         elif device.type == 'serial':
  5326.             if not device.is_class:
  5327.                 options = device.uri.split('?')[1]
  5328.                 options = options.split('+')
  5329.                 option_dict = { }
  5330.                 for option in options:
  5331.                     (name, value) = option.split('=')
  5332.                     option_dict[name] = value
  5333.                 
  5334.                 for widget, name, optionvalues in ((self.cmbNPTSerialBaud, 'baud', None), (self.cmbNPTSerialBits, 'bits', None), (self.cmbNPTSerialParity, 'parity', [
  5335.                     'none',
  5336.                     'odd',
  5337.                     'even']), (self.cmbNPTSerialFlow, 'flow', [
  5338.                     'none',
  5339.                     'soft',
  5340.                     'hard',
  5341.                     'hard'])):
  5342.                     if option_dict.has_key(name):
  5343.                         if optionvalues is None:
  5344.                             model = widget.get_model()
  5345.                             iter = model.get_iter_first()
  5346.                             nr = 0
  5347.                             while iter:
  5348.                                 value = model.get(iter, 0)[0]
  5349.                                 if value == option_dict[name]:
  5350.                                     widget.set_active(nr)
  5351.                                     break
  5352.                                 
  5353.                                 iter = model.iter_next(iter)
  5354.                                 nr += 1
  5355.                         else:
  5356.                             nr = optionvalues.index(option_dict[name])
  5357.                             widget.set_active(nr + 1)
  5358.                     optionvalues is None
  5359.                     widget.set_active(0)
  5360.                 
  5361.             
  5362.         elif device.type in ('ipp', 'http'):
  5363.             if device.uri.startswith('ipp:') or device.uri.startswith('http:'):
  5364.                 match = re.match('(ipp|https?)://([^/]+)(.*)', device.uri)
  5365.                 if match:
  5366.                     server = match.group(2)
  5367.                     printer = match.group(3)
  5368.                 else:
  5369.                     server = ''
  5370.                     printer = ''
  5371.                 self.entNPTIPPHostname.set_text(server)
  5372.                 self.entNPTIPPQueuename.set_text(printer)
  5373.                 self.lblIPPURI.set_text(device.uri)
  5374.                 self.lblIPPURI.show()
  5375.                 self.entNPTIPPQueuename.show()
  5376.                 location = server
  5377.             else:
  5378.                 self.entNPTIPPHostname.set_text('')
  5379.                 self.entNPTIPPQueuename.set_text('/printers/')
  5380.                 self.entNPTIPPQueuename.show()
  5381.                 self.lblIPPURI.hide()
  5382.         elif device.type == 'lpd':
  5383.             if device.uri.startswith('lpd'):
  5384.                 host = device.uri[6:]
  5385.                 i = host.find('/')
  5386.                 if i != -1:
  5387.                     printer = host[i + 1:]
  5388.                     host = host[:i]
  5389.                 else:
  5390.                     printer = ''
  5391.                 self.cmbentNPTLpdHost.child.set_text(host)
  5392.                 self.cmbentNPTLpdQueue.child.set_text(printer)
  5393.                 location = host
  5394.             
  5395.         elif device.uri == 'lpd':
  5396.             pass
  5397.         elif device.uri == 'smb':
  5398.             self.entSMBURI.set_text('')
  5399.             self.btnSMBVerify.set_sensitive(False)
  5400.         elif device.type == 'smb':
  5401.             self.entSMBUsername.set_text('')
  5402.             self.entSMBPassword.set_text('')
  5403.             self.entSMBURI.set_text(device.uri[6:])
  5404.             self.btnSMBVerify.set_sensitive(True)
  5405.         elif device.uri == 'hp':
  5406.             self.lblHPURI.set_text('')
  5407.         else:
  5408.             self.entNPTDevice.set_text(device.uri)
  5409.         
  5410.         try:
  5411.             if len(location) == 0 and self.device.device_class == 'direct':
  5412.                 u = os.uname()
  5413.                 location = u[1]
  5414.             
  5415.             self.entNPLocation.set_text(location)
  5416.         except:
  5417.             nonfatalException()
  5418.  
  5419.         self.setNPButtons()
  5420.  
  5421.     
  5422.     def on_btnNPTLpdProbe_clicked(self, button):
  5423.         hostname = self.cmbentNPTLpdHost.get_active_text()
  5424.         server = probe_printer.LpdServer(hostname)
  5425.         printers = server.probe()
  5426.         model = self.cmbentNPTLpdQueue.get_model()
  5427.         model.clear()
  5428.         for printer in printers:
  5429.             self.cmbentNPTLpdQueue.append_text(printer)
  5430.         
  5431.         if printers:
  5432.             self.cmbentNPTLpdQueue.set_active(0)
  5433.         
  5434.  
  5435.     
  5436.     def on_entNPTHPHostname_changed(self, ent):
  5437.         self.lblHPURI.set_text('')
  5438.         s = ent.get_text()
  5439.         self.btnHPFindQueue.set_sensitive(len(s) > 0)
  5440.         self.setNPButtons()
  5441.  
  5442.     
  5443.     def on_btnHPFindQueue_clicked(self, button):
  5444.         host = self.entNPTHPHostname.get_text()
  5445.         hplipuri = self.get_hplip_uri_for_network_printer(host, 'print')
  5446.         if hplipuri == None or hplipuri == '':
  5447.             show_error_dialog(_('No Print Shares'), _('HPLIP cannot find the device.'), self.NewPrinterWindow)
  5448.             self.entNPTHPHostname.grab_focus()
  5449.             return None
  5450.         self.lblHPURI.set_text(hplipuri)
  5451.         s = hplipuri.find('/usb/')
  5452.         if s == -1:
  5453.             s = hplipuri.find('/par/')
  5454.         
  5455.         if s == -1:
  5456.             s = hplipuri.find('/net/')
  5457.         
  5458.         if s != -1:
  5459.             s += 5
  5460.             e = hplipuri[s:].find('?')
  5461.             if e == -1:
  5462.                 e = len(hplipuri)
  5463.             
  5464.             mdl = hplipuri[s:s + e].replace('_', ' ')
  5465.             if mdl.startswith('hp ') or mdl.startswith('HP '):
  5466.                 mdl = mdl[3:]
  5467.                 self.device.make_and_model = 'HP ' + mdl
  5468.                 id = 'MFG:HP;MDL:%s;DES:HP %s;' % (mdl, mdl)
  5469.                 self.device.id = id
  5470.                 self.device.id_dict = cupshelpers.parseDeviceID(id)
  5471.             
  5472.         
  5473.  
  5474.     
  5475.     def on_entNPTNetworkHostname_changed(self, ent):
  5476.         s = ent.get_text()
  5477.         self.btnNetworkFind.set_sensitive(len(s) > 0)
  5478.         self.setNPButtons()
  5479.  
  5480.     
  5481.     def on_btnNetworkFind_clicked(self, button):
  5482.         host = self.entNPTNetworkHostname.get_text()
  5483.         uri = self.get_hplip_uri_for_network_printer(host, 'print')
  5484.         device_dict = {
  5485.             'device-class': 'network' }
  5486.         new_device = cupshelpers.Device('', **device_dict)
  5487.         if uri:
  5488.             new_device = cupshelpers.Device(uri, **device_dict)
  5489.         
  5490.         (host, uri) = self.getNetworkPrinterMakeModel(host = host, device = new_device)
  5491.         if uri:
  5492.             new_device.uri = uri
  5493.         
  5494.         debugprint('New device: %s' % new_device)
  5495.         if not new_device.uri:
  5496.             show_error_dialog(_('Not Found'), _('No printer was found at that address.'), parent = self.NewPrinterWindow)
  5497.         else:
  5498.             model = self.tvNPDevices.get_model()
  5499.             dev = PhysicalDevice(new_device)
  5500.             iter = model.insert_before(None, self.devices_find_nw_iter, row = [
  5501.                 dev.get_info(),
  5502.                 dev,
  5503.                 False])
  5504.             path = model.get_path(iter)
  5505.             self.tvNPDevices.set_cursor(path)
  5506.  
  5507.     
  5508.     def getDeviceURI(self):
  5509.         type = self.device.type
  5510.         if type == 'socket':
  5511.             host = self.entNPTDirectJetHostname.get_text()
  5512.             port = self.entNPTDirectJetPort.get_text()
  5513.             device = 'socket://' + host
  5514.             if host and port:
  5515.                 device = device + ':' + port
  5516.             
  5517.         elif type in ('http', 'ipp'):
  5518.             if self.lblIPPURI.get_property('visible'):
  5519.                 device = self.lblIPPURI.get_text()
  5520.             else:
  5521.                 device = 'ipp'
  5522.         elif type == 'lpd':
  5523.             host = self.cmbentNPTLpdHost.get_active_text()
  5524.             printer = self.cmbentNPTLpdQueue.get_active_text()
  5525.             device = 'lpd://' + host
  5526.             if printer:
  5527.                 device = device + '/' + printer
  5528.             
  5529.         elif type == 'parallel':
  5530.             device = self.device.uri
  5531.         elif type == 'scsi':
  5532.             device = ''
  5533.         elif type == 'serial':
  5534.             options = []
  5535.             for widget, name, optionvalues in ((self.cmbNPTSerialBaud, 'baud', None), (self.cmbNPTSerialBits, 'bits', None), (self.cmbNPTSerialParity, 'parity', ('none', 'odd', 'even')), (self.cmbNPTSerialFlow, 'flow', ('none', 'soft', 'hard', 'hard'))):
  5536.                 nr = widget.get_active()
  5537.                 if nr:
  5538.                     if optionvalues is not None:
  5539.                         option = optionvalues[nr - 1]
  5540.                     else:
  5541.                         option = widget.get_active_text()
  5542.                     options.append(name + '=' + option)
  5543.                     continue
  5544.             
  5545.             options = '+'.join(options)
  5546.             device = self.device.uri.split('?')[0]
  5547.             if options:
  5548.                 device = device + '?' + options
  5549.             
  5550.         elif type == 'smb':
  5551.             uri = self.entSMBURI.get_text()
  5552.             (group, host, share, u, p) = SMBURI(uri = uri).separate()
  5553.             user = ''
  5554.             password = ''
  5555.             if self.rbtnSMBAuthSet.get_active():
  5556.                 user = self.entSMBUsername.get_text()
  5557.                 password = self.entSMBPassword.get_text()
  5558.             
  5559.             uri = SMBURI(group = group, host = host, share = share, user = user, password = password).get_uri()
  5560.             device = 'smb://' + uri
  5561.         elif self.device.uri == 'hp':
  5562.             device = self.lblHPURI.get_text()
  5563.         elif not self.device.is_class:
  5564.             device = self.device.uri
  5565.         else:
  5566.             device = self.entNPTDevice.get_text()
  5567.         return device
  5568.  
  5569.     
  5570.     def on_rbtnNPFoomatic_toggled(self, widget):
  5571.         rbtn1 = self.rbtnNPFoomatic.get_active()
  5572.         rbtn2 = self.rbtnNPPPD.get_active()
  5573.         rbtn3 = self.rbtnNPDownloadableDriverSearch.get_active()
  5574.         self.tvNPMakes.set_sensitive(rbtn1)
  5575.         self.filechooserPPD.set_sensitive(rbtn2)
  5576.         if rbtn1:
  5577.             page = 0
  5578.         
  5579.         if rbtn2:
  5580.             page = 1
  5581.         
  5582.         if rbtn3:
  5583.             page = 2
  5584.         
  5585.         self.ntbkPPDSource.set_current_page(page)
  5586.         if not rbtn3 and self.openprinting_query_handle:
  5587.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  5588.             self.openprinting_query_handle = None
  5589.             self.btnNPDownloadableDriverSearch_label.set_text(_('Search'))
  5590.             model = gtk.ListStore(str, str)
  5591.             combobox = self.cmbNPDownloadableDriverFoundPrinters
  5592.             combobox.set_model(model)
  5593.             combobox.set_sensitive(False)
  5594.         
  5595.         for widget in [
  5596.             self.entNPDownloadableDriverSearch,
  5597.             self.cmbNPDownloadableDriverFoundPrinters]:
  5598.             widget.set_sensitive(rbtn3)
  5599.         
  5600.         if rbtn3:
  5601.             pass
  5602.         self.btnNPDownloadableDriverSearch.set_sensitive(self.openprinting_query_handle == None)
  5603.         self.setNPButtons()
  5604.  
  5605.     
  5606.     def on_filechooserPPD_selection_changed(self, widget):
  5607.         self.setNPButtons()
  5608.  
  5609.     
  5610.     def on_btnNPDownloadableDriverSearch_clicked(self, widget):
  5611.         if self.openprinting_query_handle != None:
  5612.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  5613.             self.openprinting_query_handle = None
  5614.         
  5615.         widget.set_sensitive(False)
  5616.         label = self.btnNPDownloadableDriverSearch_label
  5617.         label.set_text(_('Searching'))
  5618.         searchterm = self.entNPDownloadableDriverSearch.get_text()
  5619.         self.openprinting_query_handle = self.openprinting.searchPrinters(searchterm, self.openprinting_printers_found)
  5620.         self.cmbNPDownloadableDriverFoundPrinters.set_sensitive(False)
  5621.  
  5622.     
  5623.     def openprinting_printers_found(self, status, user_data, printers):
  5624.         self.openprinting_query_handle = None
  5625.         button = self.btnNPDownloadableDriverSearch
  5626.         label = self.btnNPDownloadableDriverSearch_label
  5627.         gtk.gdk.threads_enter()
  5628.         
  5629.         try:
  5630.             label.set_text(_('Search'))
  5631.             button.set_sensitive(True)
  5632.             if status != 0:
  5633.                 print printers
  5634.                 print traceback.extract_tb(printers[2], limit = None)
  5635.                 gtk.gdk.threads_leave()
  5636.                 return None
  5637.             model = gtk.ListStore(str, str)
  5638.             sorted_list = []
  5639.             for id, name in printers.iteritems():
  5640.                 sorted_list.append((id, name))
  5641.             
  5642.             sorted_list.sort((lambda x, y: cups.modelSort(x[1], y[1])))
  5643.             sought = self.entNPDownloadableDriverSearch.get_text().lower()
  5644.             select_index = 0
  5645.             for id, name in sorted_list:
  5646.                 iter = model.append(None)
  5647.                 model.set_value(iter, 0, name)
  5648.                 model.set_value(iter, 1, id)
  5649.                 if name.lower() == sought:
  5650.                     select_index = model.get_path(iter)[0]
  5651.                     continue
  5652.                 None if len(printers) != 1 else status != 0
  5653.             
  5654.             combobox = self.cmbNPDownloadableDriverFoundPrinters
  5655.             combobox.set_model(model)
  5656.             combobox.set_active(select_index)
  5657.             combobox.set_sensitive(True)
  5658.             self.setNPButtons()
  5659.         except:
  5660.             nonfatalException()
  5661.  
  5662.         gtk.gdk.threads_leave()
  5663.  
  5664.     
  5665.     def on_cmbNPDownloadableDriverFoundPrinters_changed(self, widget):
  5666.         self.setNPButtons()
  5667.         if self.openprinting_query_handle != None:
  5668.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  5669.             self.openprinting_query_handle = None
  5670.             self.drivers_lock.release()
  5671.         
  5672.         model = widget.get_model()
  5673.         iter = widget.get_active_iter()
  5674.         if iter:
  5675.             id = model.get_value(iter, 1)
  5676.         else:
  5677.             id = None
  5678.         if id == None:
  5679.             return None
  5680.         debugprint('Query drivers for %s' % id)
  5681.         self.drivers_lock.acquire(0)
  5682.         extra_options = dict()
  5683.         if self.DOWNLOADABLE_ONLYPPD:
  5684.             extra_options['onlyppdfiles'] = '1'
  5685.         
  5686.         self.openprinting_query_handle = self.openprinting.listDrivers(id, self.openprinting_drivers_found, extra_options = extra_options)
  5687.  
  5688.     
  5689.     def openprinting_drivers_found(self, status, user_data, drivers):
  5690.         if status != 0:
  5691.             print drivers
  5692.             print traceback.extract_tb(drivers[2], limit = None)
  5693.             return None
  5694.         self.openprinting_query_handle = None
  5695.         self.downloadable_drivers = drivers
  5696.         debugprint('Drivers query completed: %s' % drivers.keys())
  5697.         self.drivers_lock.release()
  5698.  
  5699.     
  5700.     def fillDownloadableDrivers(self):
  5701.         self.lblNPDownloadableDriverSupplier.set_text('')
  5702.         self.lblNPDownloadableDriverLicense.set_text('')
  5703.         self.lblNPDownloadableDriverDescription.set_text('')
  5704.         self.lblNPDownloadableDriverSupportContacts.set_text('')
  5705.         self.rbtnNPDownloadLicenseNo.set_active(True)
  5706.         self.frmNPDownloadableDriverLicenseTerms.hide()
  5707.         drivers = self.downloadable_drivers
  5708.         model = gtk.ListStore(str, gobject.TYPE_PYOBJECT)
  5709.         recommended_iter = None
  5710.         first_iter = None
  5711.         for driver in drivers.values():
  5712.             iter = model.append(None)
  5713.             if first_iter == None:
  5714.                 first_iter = iter
  5715.             
  5716.             model.set_value(iter, 0, driver['name'])
  5717.             model.set_value(iter, 1, driver)
  5718.             if driver['recommended']:
  5719.                 recommended_iter = iter
  5720.                 continue
  5721.         
  5722.         if recommended_iter == None:
  5723.             recommended_iter = first_iter
  5724.         
  5725.         treeview = self.tvNPDownloadableDrivers
  5726.         treeview.set_model(model)
  5727.         if recommended_iter != None:
  5728.             treeview.get_selection().select_iter(recommended_iter)
  5729.         
  5730.  
  5731.     
  5732.     def on_rbtnNPDownloadLicense_toggled(self, widget):
  5733.         self.setNPButtons()
  5734.  
  5735.     
  5736.     def fillMakeList(self):
  5737.         makes = self.ppds.getMakes()
  5738.         model = self.tvNPMakes.get_model()
  5739.         model.clear()
  5740.         found = False
  5741.         for make in makes:
  5742.             iter = model.append((make,))
  5743.             if make.lower() == self.auto_make.lower():
  5744.                 path = model.get_path(iter)
  5745.                 self.tvNPMakes.set_cursor(path)
  5746.                 self.tvNPMakes.scroll_to_cell(path, None, True, 0.5, 0.5)
  5747.                 found = True
  5748.                 continue
  5749.         
  5750.         if not found:
  5751.             self.tvNPMakes.set_cursor(0)
  5752.             self.tvNPMakes.scroll_to_cell(0, None, True, 0, 0)
  5753.         
  5754.         search = ''
  5755.         if self.auto_make != None:
  5756.             search += self.auto_make
  5757.             if self.auto_model != None:
  5758.                 search += ' ' + self.auto_model
  5759.             
  5760.         
  5761.         self.entNPDownloadableDriverSearch.set_text(search)
  5762.  
  5763.     
  5764.     def on_tvNPMakes_cursor_changed(self, tvNPMakes):
  5765.         (path, column) = tvNPMakes.get_cursor()
  5766.         if path != None:
  5767.             model = tvNPMakes.get_model()
  5768.             iter = model.get_iter(path)
  5769.             self.NPMake = model.get(iter, 0)[0]
  5770.             self.fillModelList()
  5771.         
  5772.  
  5773.     
  5774.     def fillModelList(self):
  5775.         models = self.ppds.getModels(self.NPMake)
  5776.         model = self.tvNPModels.get_model()
  5777.         model.clear()
  5778.         selected = False
  5779.         for pmodel in models:
  5780.             iter = model.append((pmodel,))
  5781.             if self.NPMake.lower() == self.auto_make.lower() and pmodel.lower() == self.auto_model.lower():
  5782.                 path = model.get_path(iter)
  5783.                 self.tvNPModels.set_cursor(path)
  5784.                 self.tvNPModels.scroll_to_cell(path, None, True, 0.5, 0.5)
  5785.                 selected = True
  5786.                 continue
  5787.         
  5788.         if not selected:
  5789.             self.tvNPModels.set_cursor(0)
  5790.             self.tvNPModels.scroll_to_cell(0, None, True, 0, 0)
  5791.         
  5792.         self.tvNPModels.columns_autosize()
  5793.  
  5794.     
  5795.     def fillDriverList(self, pmake, pmodel):
  5796.         self.NPModel = pmodel
  5797.         model = self.tvNPDrivers.get_model()
  5798.         model.clear()
  5799.         ppds = self.ppds.getInfoFromModel(pmake, pmodel)
  5800.         self.NPDrivers = self.ppds.orderPPDNamesByPreference(ppds.keys(), self.jockey_installed_files)
  5801.         for i in range(len(self.NPDrivers)):
  5802.             ppd = ppds[self.NPDrivers[i]]
  5803.             driver = ppd['ppd-make-and-model']
  5804.             driver = driver.replace(' (recommended)', '')
  5805.             
  5806.             try:
  5807.                 lpostfix = ' [%s]' % ppd['ppd-natural-language']
  5808.                 driver += lpostfix
  5809.             except KeyError:
  5810.                 pass
  5811.  
  5812.             if i == 0:
  5813.                 iter = model.append((driver + _(' (recommended)'),))
  5814.                 path = model.get_path(iter)
  5815.                 self.tvNPDrivers.get_selection().select_path(path)
  5816.                 self.tvNPDrivers.scroll_to_cell(path, None, True, 0.5, 0)
  5817.                 continue
  5818.             model.append((driver,))
  5819.         
  5820.         self.tvNPDrivers.columns_autosize()
  5821.  
  5822.     
  5823.     def NPDriversTooltips(self, model, path, col):
  5824.         drivername = self.NPDrivers[path[0]]
  5825.         ppddict = self.ppds.getInfoFromPPDName(drivername)
  5826.         markup = ppddict['ppd-make-and-model']
  5827.         if drivername.startswith('foomatic:'):
  5828.             markup += ' '
  5829.             markup += _('This PPD is generated by foomatic.')
  5830.         
  5831.         return markup
  5832.  
  5833.     
  5834.     def on_tvNPModels_cursor_changed(self, widget):
  5835.         (path, column) = widget.get_cursor()
  5836.         if path != None:
  5837.             model = widget.get_model()
  5838.             iter = model.get_iter(path)
  5839.             pmodel = model.get(iter, 0)[0]
  5840.             self.fillDriverList(self.NPMake, pmodel)
  5841.             self.on_tvNPDrivers_cursor_changed(self.tvNPDrivers)
  5842.         
  5843.  
  5844.     
  5845.     def on_tvNPDrivers_cursor_changed(self, widget):
  5846.         self.setNPButtons()
  5847.  
  5848.     
  5849.     def on_tvNPDownloadableDrivers_cursor_changed(self, widget):
  5850.         (model, iter) = widget.get_selection().get_selected()
  5851.         if not iter:
  5852.             (path, column) = widget.get_cursor()
  5853.             iter = model.get_iter(path)
  5854.         
  5855.         driver = model.get_value(iter, 1)
  5856.         import pprint
  5857.         pprint.pprint(driver)
  5858.         self.ntbkNPDownloadableDriverProperties.set_current_page(1)
  5859.         supplier = driver.get('supplier', _('OpenPrinting'))
  5860.         vendor = self.cbNPDownloadableDriverSupplierVendor
  5861.         active = driver['manufacturersupplied']
  5862.         
  5863.         def set_protect_active(widget, active):
  5864.             widget.set_active(active)
  5865.             widget.set_data('protect_active', active)
  5866.  
  5867.         set_protect_active(vendor, active)
  5868.         self.lblNPDownloadableDriverSupplier.set_text(supplier)
  5869.         license = driver.get('license', _('Distributable'))
  5870.         patents = self.cbNPDownloadableDriverLicensePatents
  5871.         free = self.cbNPDownloadableDriverLicenseFree
  5872.         set_protect_active(patents, driver['patents'])
  5873.         set_protect_active(free, driver['freesoftware'])
  5874.         self.lblNPDownloadableDriverLicense.set_text(license)
  5875.         description = driver.get('shortdescription', _('None'))
  5876.         self.lblNPDownloadableDriverDescription.set_markup(description)
  5877.         functionality = driver['functionality']
  5878.         for field in [
  5879.             'Graphics',
  5880.             'LineArt',
  5881.             'Photo',
  5882.             'Text']:
  5883.             key = field.lower()
  5884.             value = None
  5885.             hs = self.__dict__.get('hsDownloadableDriverPerf%s' % field)
  5886.             unknown = self.__dict__.get('lblDownloadableDriverPerf%sUnknown' % field)
  5887.             if functionality.has_key(key):
  5888.                 if hs:
  5889.                     
  5890.                     try:
  5891.                         value = int(functionality[key])
  5892.                         hs.set_value(value)
  5893.                         hs.show_all()
  5894.                         unknown.hide()
  5895.  
  5896.                 
  5897.             
  5898.             if value == None:
  5899.                 hs.hide()
  5900.                 unknown.show_all()
  5901.                 continue
  5902.         
  5903.         supportcontacts = ''
  5904.         if driver.has_key('supportcontacts'):
  5905.             for supportentry in driver['supportcontacts']:
  5906.                 if supportentry['name']:
  5907.                     supportcontact = ' - ' + supportentry['name']
  5908.                     supportcontact_extra = ''
  5909.                     if supportentry['url']:
  5910.                         supportcontact_extra = supportcontact_extra + supportentry['url']
  5911.                     
  5912.                     if supportentry['level']:
  5913.                         if supportcontact_extra:
  5914.                             supportcontact_extra = supportcontact_extra + _(', ')
  5915.                         
  5916.                         supportcontact_extra = supportcontact_extra + supportentry['level']
  5917.                     
  5918.                     if supportcontact_extra:
  5919.                         supportcontact = supportcontact + _('\n(%s)') % supportcontact_extra
  5920.                         if supportcontacts:
  5921.                             supportcontacts = supportcontacts + '\n'
  5922.                         
  5923.                         supportcontacts = supportcontacts + supportcontact
  5924.                     
  5925.                 supportcontact_extra
  5926.             
  5927.         
  5928.         if not supportcontacts:
  5929.             supportcontacts = _('No support contacts known')
  5930.         
  5931.         self.lblNPDownloadableDriverSupportContacts.set_text(supportcontacts)
  5932.         if driver.has_key('licensetext'):
  5933.             self.frmNPDownloadableDriverLicenseTerms.show()
  5934.             terms = driver.get('licensetext', _('Not specified.'))
  5935.             self.tvNPDownloadableDriverLicense.get_buffer().set_text(terms)
  5936.         else:
  5937.             self.frmNPDownloadableDriverLicenseTerms.hide()
  5938.         if not driver['nonfreesoftware'] and not driver['patents']:
  5939.             self.rbtnNPDownloadLicenseYes.set_active(True)
  5940.             self.rbtnNPDownloadLicenseYes.hide()
  5941.             self.rbtnNPDownloadLicenseNo.hide()
  5942.         else:
  5943.             self.rbtnNPDownloadLicenseNo.set_active(True)
  5944.             self.rbtnNPDownloadLicenseYes.show()
  5945.             self.rbtnNPDownloadLicenseNo.show()
  5946.             self.frmNPDownloadableDriverLicenseTerms.show()
  5947.             terms = driver.get('licensetext', _('Not specified.'))
  5948.             self.tvNPDownloadableDriverLicense.get_buffer().set_text(terms)
  5949.         self.setNPButtons()
  5950.  
  5951.     
  5952.     def getNPPPD(self):
  5953.         
  5954.         try:
  5955.             if self.rbtnNPFoomatic.get_active():
  5956.                 (model, iter) = self.tvNPDrivers.get_selection().get_selected()
  5957.                 nr = model.get_path(iter)[0]
  5958.                 ppd = self.NPDrivers[nr]
  5959.             elif self.rbtnNPPPD.get_active():
  5960.                 ppd = cups.PPD(self.filechooserPPD.get_filename())
  5961.             else:
  5962.                 treeview = self.tvNPDownloadableDrivers
  5963.                 (model, iter) = treeview.get_selection().get_selected()
  5964.                 driver = model.get_value(iter, 1)
  5965.                 if driver.has_key('ppds'):
  5966.                     if len(driver['ppds']) > 0:
  5967.                         file_to_download = driver['ppds'][0]
  5968.                         debugprint('ppd file to download [' + file_to_download + ']')
  5969.                         file_to_download = file_to_download.strip()
  5970.                         if len(file_to_download) > 0:
  5971.                             ppdurlobj = urllib.urlopen(file_to_download)
  5972.                             ppdcontent = ppdurlobj.read()
  5973.                             ppdurlobj.close()
  5974.                             (tmpfd, ppdname) = tempfile.mkstemp()
  5975.                             debugprint(ppdname)
  5976.                             ppdfile = os.fdopen(tmpfd, 'w')
  5977.                             ppdfile.write(ppdcontent)
  5978.                             ppdfile.close()
  5979.                             ppd = cups.PPD(ppdname)
  5980.                             os.unlink(ppdname)
  5981.                         
  5982.                     
  5983.         except RuntimeError:
  5984.             e = None
  5985.             debugprint('RuntimeError: ' + str(e))
  5986.             if self.rbtnNPFoomatic.get_active():
  5987.                 err_title = _('Database error')
  5988.                 err_text = _("The '%s' driver cannot be used with printer '%s %s'.")
  5989.                 (model, iter) = self.tvNPDrivers.get_selection().get_selected()
  5990.                 nr = model.get_path(iter)[0]
  5991.                 driver = self.NPDrivers[nr]
  5992.                 if driver.startswith('gutenprint'):
  5993.                     err = _("You will need to install the '%s' package in order to use this driver.") % 'gutenprint-foomatic'
  5994.                 else:
  5995.                     err = err_text % (driver, self.NPMake, self.NPModel)
  5996.             elif self.rbtnNPPPD.get_active():
  5997.                 err_title = _('PPD error')
  5998.                 filename = self.filechooserPPD.get_filename()
  5999.                 err = _('Failed to read PPD file.  Possible reason follows:') + '\n'
  6000.                 
  6001.                 try:
  6002.                     p = subprocess.Popen([
  6003.                         '/usr/bin/cupstestppd',
  6004.                         '-rvv',
  6005.                         filename], stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  6006.                     (stdout, stderr) = p.communicate()
  6007.                     err += stdout
  6008.                 raise 
  6009.  
  6010.             else:
  6011.                 err_title = _('Downloadable drivers')
  6012.                 err = _('Failed to download PPD.')
  6013.             show_error_dialog(err_title, err, self.NewPrinterWindow)
  6014.             return None
  6015.         else:
  6016.             debugprint('ppd: ' + repr(ppd))
  6017.             if isinstance(ppd, str) or isinstance(ppd, unicode):
  6018.                 self.mainapp.cups._begin_operation(_('fetching PPD'))
  6019.                 
  6020.                 try:
  6021.                     if ppd != 'raw':
  6022.                         f = self.mainapp.cups.getServerPPD(ppd)
  6023.                         ppd = cups.PPD(f)
  6024.                         os.unlink(f)
  6025.                 except RuntimeError:
  6026.                     nonfatalException()
  6027.                     debugprint('libcups from CUPS 1.3 not available: never mind')
  6028.                 except cups.IPPError:
  6029.                     nonfatalException()
  6030.                     debugprint('CUPS 1.3 server not available: never mind')
  6031.  
  6032.                 self.mainapp.cups._end_operation()
  6033.             
  6034.  
  6035.         return ppd
  6036.  
  6037.     
  6038.     def fillNPInstallableOptions(self):
  6039.         debugprint('Examining installable options')
  6040.         self.installable_options = False
  6041.         self.options = { }
  6042.         container = self.vbNPInstallOptions
  6043.         for child in container.get_children():
  6044.             container.remove(child)
  6045.         
  6046.         if not self.ppd:
  6047.             l = gtk.Label(_('No Installable Options'))
  6048.             container.add(l)
  6049.             l.show()
  6050.             debugprint('No PPD so no installable options')
  6051.             return None
  6052.         for group in self.ppd.optionGroups:
  6053.             if group.name != 'InstallableOptions':
  6054.                 continue
  6055.             
  6056.             self.installable_options = True
  6057.             table = gtk.Table(1, 3, False)
  6058.             table.set_col_spacings(6)
  6059.             table.set_row_spacings(6)
  6060.             container.add(table)
  6061.             rows = 0
  6062.             for nr, option in enumerate(group.options):
  6063.                 if option.keyword == 'PageRegion':
  6064.                     continue
  6065.                 
  6066.                 rows += 1
  6067.                 table.resize(rows, 3)
  6068.                 o = OptionWidget(option, self.ppd, self)
  6069.                 table.attach(o.conflictIcon, 0, 1, nr, nr + 1, 0, 0, 0, 0)
  6070.                 hbox = gtk.HBox()
  6071.                 if o.label:
  6072.                     a = gtk.Alignment(0.5, 0.5, 1, 1)
  6073.                     a.set_padding(0, 0, 0, 6)
  6074.                     a.add(o.label)
  6075.                     table.attach(a, 1, 2, nr, nr + 1, gtk.FILL, 0, 0, 0)
  6076.                     table.attach(hbox, 2, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  6077.                 else:
  6078.                     table.attach(hbox, 1, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  6079.                 hbox.pack_start(o.selector, False)
  6080.                 self.options[option.keyword] = o
  6081.             
  6082.         
  6083.         if not self.installable_options:
  6084.             l = gtk.Label(_('No Installable Options'))
  6085.             container.add(l)
  6086.             l.show()
  6087.         
  6088.         self.scrNPInstallableOptions.hide()
  6089.         self.scrNPInstallableOptions.show_all()
  6090.  
  6091.     
  6092.     def on_btnNPApply_clicked(self, widget):
  6093.         if self.dialog_mode in ('class', 'printer', 'printer_with_uri'):
  6094.             name = unicode(self.entNPName.get_text())
  6095.             location = unicode(self.entNPLocation.get_text())
  6096.             info = unicode(self.entNPDescription.get_text())
  6097.         else:
  6098.             name = self.mainapp.printer.name
  6099.         check = False
  6100.         checkppd = None
  6101.         ppd = self.ppd
  6102.         if self.dialog_mode == 'class':
  6103.             members = getCurrentClassMembers(self.tvNCMembers)
  6104.             
  6105.             try:
  6106.                 for member in members:
  6107.                     self.mainapp.cups.addPrinterToClass(member, name)
  6108.             except cups.IPPError:
  6109.                 (e, msg) = None
  6110.                 self.show_IPP_Error(e, msg)
  6111.                 return None
  6112.             
  6113.  
  6114.         None<EXCEPTION MATCH>cups.IPPError
  6115.         if self.dialog_mode == 'printer' or self.dialog_mode == 'printer_with_uri':
  6116.             uri = None
  6117.             if self.device.uri:
  6118.                 uri = self.device.uri
  6119.             else:
  6120.                 uri = self.getDeviceURI()
  6121.             if not self.ppd:
  6122.                 self.nextNPTab(-1)
  6123.                 return None
  6124.             for option in self.options.itervalues():
  6125.                 option.writeback()
  6126.             
  6127.             self.busy(self.NewPrinterWindow)
  6128.             while gtk.events_pending():
  6129.                 gtk.main_iteration()
  6130.                 continue
  6131.                 self.ppd
  6132.             self.mainapp.cups._begin_operation(_('adding printer %s') % name)
  6133.             
  6134.             try:
  6135.                 if isinstance(ppd, str) or isinstance(ppd, unicode):
  6136.                     self.mainapp.cups.addPrinter(name, ppdname = ppd, device = uri, info = info, location = location)
  6137.                     check = True
  6138.                 elif ppd is None:
  6139.                     self.mainapp.cups.addPrinter(name, device = uri, info = info, location = location)
  6140.                 else:
  6141.                     cupshelpers.setPPDPageSize(ppd, self.language[0])
  6142.                     self.mainapp.cups.addPrinter(name, ppd = ppd, device = uri, info = info, location = location)
  6143.                     check = True
  6144.                     checkppd = ppd
  6145.             except cups.IPPError:
  6146.                 (e, msg) = None
  6147.                 self.ready(self.NewPrinterWindow)
  6148.                 self.show_IPP_Error(e, msg)
  6149.                 self.mainapp.cups._end_operation()
  6150.                 return None
  6151.                 self.ready(self.NewPrinterWindow)
  6152.                 self.mainapp.cups._end_operation()
  6153.                 fatalException(1)
  6154.  
  6155.             self.mainapp.cups._end_operation()
  6156.             self.ready(self.NewPrinterWindow)
  6157.         
  6158.         if self.dialog_mode in ('class', 'printer', 'printer_with_uri'):
  6159.             self.mainapp.cups._begin_operation(_('modifying printer %s') % name)
  6160.             
  6161.             try:
  6162.                 cupshelpers.activateNewPrinter(self.mainapp.cups, name)
  6163.                 self.mainapp.cups.setPrinterLocation(name, location)
  6164.                 self.mainapp.cups.setPrinterInfo(name, info)
  6165.             except cups.IPPError:
  6166.                 (e, msg) = None
  6167.                 self.show_IPP_Error(e, msg)
  6168.                 self.mainapp.cups._end_operation()
  6169.                 return None
  6170.  
  6171.             self.mainapp.cups._end_operation()
  6172.         elif self.dialog_mode == 'device':
  6173.             self.mainapp.cups._begin_operation(_('modifying printer %s') % name)
  6174.             
  6175.             try:
  6176.                 uri = self.getDeviceURI()
  6177.                 if not self.install_hplip_plugin(uri):
  6178.                     self.on_NPCancel(None)
  6179.                     return None
  6180.                 self.mainapp.cups.addPrinter(name, device = uri)
  6181.             except cups.IPPError:
  6182.                 (e, msg) = None
  6183.                 self.show_IPP_Error(e, msg)
  6184.                 self.mainapp.cups._end_operation()
  6185.                 return None
  6186.  
  6187.             self.mainapp.cups._end_operation()
  6188.         elif self.dialog_mode == 'ppd':
  6189.             if not ppd:
  6190.                 ppd = self.ppd = self.getNPPPD()
  6191.                 if not ppd:
  6192.                     self.nextNPTab(-1)
  6193.                     return None
  6194.             
  6195.             self.mainapp.cups._begin_operation(_('modifying printer %s') % name)
  6196.             raw = False
  6197.             if isinstance(ppd, str) or isinstance(ppd, unicode):
  6198.                 if self.rbtnChangePPDasIs.get_active():
  6199.                     
  6200.                     try:
  6201.                         self.mainapp.cups.addPrinter(name, ppdname = 'raw')
  6202.                     except cups.IPPError:
  6203.                         (e, msg) = None
  6204.                         self.show_IPP_Error(e, msg)
  6205.                     except:
  6206.                         None<EXCEPTION MATCH>cups.IPPError
  6207.                     
  6208.  
  6209.                 None<EXCEPTION MATCH>cups.IPPError
  6210.                 
  6211.                 try:
  6212.                     self.mainapp.cups.addPrinter(name, ppdname = ppd)
  6213.                 except cups.IPPError:
  6214.                     (e, msg) = None
  6215.                     self.show_IPP_Error(e, msg)
  6216.                     self.mainapp.cups._end_operation()
  6217.                     return None
  6218.  
  6219.                 
  6220.                 try:
  6221.                     filename = self.mainapp.cups.getPPD(name)
  6222.                     ppd = cups.PPD(filename)
  6223.                     os.unlink(filename)
  6224.                 except cups.IPPError:
  6225.                     (e, msg) = None
  6226.                     if e == cups.IPP_NOT_FOUND:
  6227.                         raw = True
  6228.                     else:
  6229.                         self.show_IPP_Error(e, msg)
  6230.                         self.mainapp.cups._end_operation()
  6231.                         return None
  6232.                     e == cups.IPP_NOT_FOUND
  6233.                 
  6234.  
  6235.             None<EXCEPTION MATCH>cups.IPPError
  6236.             if not self.rbtnChangePPDasIs.get_active() and isinstance(self.mainapp.ppd, cups.PPD):
  6237.                 cupshelpers.copyPPDOptions(self.mainapp.ppd, ppd)
  6238.             else:
  6239.                 for option in self.options.itervalues():
  6240.                     option.writeback()
  6241.                 
  6242.                 cupshelpers.setPPDPageSize(ppd, self.language[0])
  6243.             
  6244.             try:
  6245.                 self.mainapp.cups.addPrinter(name, ppd = ppd)
  6246.             except cups.IPPError:
  6247.                 (e, msg) = None
  6248.                 self.show_IPP_Error(e, msg)
  6249.  
  6250.             self.mainapp.cups._end_operation()
  6251.             if not raw:
  6252.                 check = True
  6253.                 checkppd = ppd
  6254.             
  6255.         
  6256.         self.NewPrinterWindow.hide()
  6257.         self.mainapp.populateList()
  6258.         self.mainapp.fillPrinterTab(name)
  6259.         if check:
  6260.             
  6261.             try:
  6262.                 self.checkDriverExists(name, ppd = checkppd)
  6263.             except:
  6264.                 nonfatalException()
  6265.  
  6266.             
  6267.             try:
  6268.                 option = self.mainapp.server_side_options['media']
  6269.                 if option.get_current_value() == None:
  6270.                     debugprint('Invalid media option: resetting')
  6271.                     option.reset()
  6272.                     self.mainapp.changed.add(option)
  6273.                     self.mainapp.save_printer(self.mainapp.printer)
  6274.             except KeyError:
  6275.                 pass
  6276.             except:
  6277.                 None<EXCEPTION MATCH>KeyError
  6278.                 nonfatalException()
  6279.             
  6280.  
  6281.         None<EXCEPTION MATCH>KeyError
  6282.         if (self.dialog_mode == 'printer' or self.dialog_mode == 'printer_with_uri') and self.mainapp.ppd != False:
  6283.             q = gtk.MessageDialog(self.mainapp.PrintersWindow, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _('Would you like to print a test page?'))
  6284.             response = q.run()
  6285.             q.destroy()
  6286.             if response == gtk.RESPONSE_YES:
  6287.                 self.mainapp.display_properties_dialog_for(name)
  6288.                 self.mainapp.btnPrintTestPage.clicked()
  6289.             
  6290.         
  6291.  
  6292.     
  6293.     def checkDriverExists(self, name, ppd = None):
  6294.         '''Check that the driver for an existing queue actually
  6295.         exists, and prompt to install the appropriate package
  6296.         if not.
  6297.  
  6298.         ppd: cups.PPD object, if already created'''
  6299.         server = cups.getServer()
  6300.         if not server == 'localhost' and server == '127.0.0.1' and server == '::1' or server[0] == '/':
  6301.             return None
  6302.         if not ppd:
  6303.             
  6304.             try:
  6305.                 filename = self.mainapp.cups.getPPD(name)
  6306.             except cups.IPPError:
  6307.                 server[0] == '/'
  6308.                 (e, msg) = server[0] == '/'
  6309.                 if e == cups.IPP_NOT_FOUND:
  6310.                     return None
  6311.                 self.show_IPP_Error(e, msg)
  6312.                 return None
  6313.             except:
  6314.                 e == cups.IPP_NOT_FOUND
  6315.  
  6316.             ppd = cups.PPD(filename)
  6317.             os.unlink(filename)
  6318.         
  6319.         (pkgs, exes) = cupshelpers.missingPackagesAndExecutables(ppd)
  6320.         if len(pkgs) > 0 or len(exes) > 0:
  6321.             can_install = False
  6322.             if len(pkgs) > 0:
  6323.                 
  6324.                 try:
  6325.                     pk = installpackage.PackageKit()
  6326.                     can_install = True
  6327.  
  6328.             
  6329.             if can_install and len(pkgs) > 0:
  6330.                 pkg = pkgs[0]
  6331.                 install_text = '<span weight="bold" size="larger">' + _('Install driver') + '</span>\n\n' + _("Printer '%s' requires the %s package but it is not currently installed.") % (name, pkg)
  6332.                 dialog = self.InstallDialog
  6333.                 self.lblInstall.set_markup(install_text)
  6334.                 dialog.set_transient_for(self.mainapp.PrintersWindow)
  6335.                 response = dialog.run()
  6336.                 dialog.hide()
  6337.                 if response == gtk.RESPONSE_OK:
  6338.                     
  6339.                     try:
  6340.                         xid = self.mainapp.PrintersWindow.window.xid
  6341.                         pk.InstallPackageName(xid, 0, pkg)
  6342.  
  6343.                 
  6344.             else:
  6345.                 show_error_dialog(_('Missing driver'), _("Printer '%s' requires the '%s' program but it is not currently installed.  Please install it before using this printer.") % (name, exes + pkgs[0]), self.mainapp.PrintersWindow)
  6346.         
  6347.  
  6348.  
  6349.  
  6350. def main(setup_printer = None, configure_printer = None, change_ppd = False, devid = '', print_test_page = False, focus_on_map = True):
  6351.     cups.setUser(os.environ.get('CUPS_USER', cups.getUser()))
  6352.     gtk.gdk.threads_init()
  6353.     mainwindow = GUI(setup_printer, configure_printer, change_ppd, devid, print_test_page, focus_on_map)
  6354.     if gtk.__dict__.has_key('main'):
  6355.         gtk.main()
  6356.     else:
  6357.         gtk.mainloop()
  6358.  
  6359. if __name__ == '__main__':
  6360.     import getopt
  6361.     
  6362.     try:
  6363.         (opts, args) = getopt.gnu_getopt(sys.argv[1:], '', [
  6364.             'setup-printer=',
  6365.             'configure-printer=',
  6366.             'choose-driver=',
  6367.             'devid=',
  6368.             'print-test-page=',
  6369.             'no-focus-on-map',
  6370.             'debug'])
  6371.     except getopt.GetoptError:
  6372.         show_help()
  6373.         sys.exit(1)
  6374.  
  6375.     setup_printer = None
  6376.     configure_printer = None
  6377.     change_ppd = False
  6378.     print_test_page = False
  6379.     focus_on_map = True
  6380.     devid = ''
  6381.     for opt, optarg in opts:
  6382.         if opt == '--configure-printer' and opt == '--choose-driver' or opt == '--print-test-page':
  6383.             configure_printer = optarg
  6384.             if opt == '--choose-driver':
  6385.                 change_ppd = True
  6386.             elif opt == '--print-test-page':
  6387.                 print_test_page = True
  6388.             
  6389.         elif opt == '--setup-printer':
  6390.             setup_printer = optarg
  6391.         elif opt == '--devid':
  6392.             devid = optarg
  6393.         elif opt == '--no-focus-on-map':
  6394.             focus_on_map = False
  6395.         elif opt == '--debug':
  6396.             set_debugging(True)
  6397.         
  6398.     
  6399.     main(setup_printer, configure_printer, change_ppd, devid, print_test_page, focus_on_map)
  6400.  
  6401.